Записки самоучки

Май 26, 2008

jQuery обновился, опять

Filed under: JavaScript,jQuery — 4matic @ 6:55 пп

Пока я ездил на выходных Киев-Запорожье-Киев jQuery обновился до версии 1.2.6. Данных об изменениях пока нет, но, думаю, что изменения существенные, т.к. между выходами версий 1.2.5 и 1.2.6 прошёл небольшой и многое исправить не смогли бы, а, вот, что-то важное — вполне.

Вобщем, обновляемся. Я уже обновился — пока все работает нормально.

Май 23, 2008

Обновился jQuery, jQuery UI

Filed under: Глюки,JavaScript,jQuery — 4matic @ 9:54 пп

Как-то незаметно для меня обновился jQuery. Причём, версию 1.2.4 я пропустил, поэтому обновился сразу до 1.2.5. Пока полёт нормальный. Так же обновился jQuery UI до версии четвёртой беты. Очень много изменилось в расширении Datepicker. Частично из изменился API:

Version 3.4.x Updates

  • Formatting updates to demo page.
  • Code optimizations.
  • Added Bulgarian translation.
  • Starts with a semicolon.
  • Fixed scrolled overflow elements.
  • Fixed wiki demo in IE and Safari.
  • Added lithuanian translation.
  • Consolidate formatting parameters for formatDate and parseDate.
  • Replace hasClass() with is().
  • Allow control characters to be typed (copy/paste).
  • Fix width bug for multiple months display.
  • Trigger button now toggles date picker.
  • Default date is always within min/max date restrictions.
  • Use reverse animations for hide based on showAnim setting.
  • Added onClose setting.
  • Apply both datepicker_currentDay and datepicker_today styles if applicable.
  • Default date is not depicted as the current date.
  • Fix jump on Next when showing multiple months and selecting in later months.

Functions renamed for jQuery UI v1.5

  • attachDatepicker is now datepicker
  • removeDatepicker is now datepicker(«destroy»)
  • changeDatepicker is now datepicker(«change»)
  • disableDatepicker is now datepicker(«disable»)
  • enableDatepicker is now datepicker(«enable»)
  • isDisabledDatepicker is now datepicker(«isDisabled»)
  • showDatepicker is now datepicker(«show»)
  • getDateDatepicker is now datepicker(«getDate»)
  • setDateDatepicker is now datepicker(«setDate», …)

Version 3.3 Updates

Changes made to the core for constancy with jQuery UI

  • Changed $(selector).datepicker() to $(selector).attachDatepicker().
  • Changed $.datepicker.enableFor(control) to $(selector).enableDatepicker().
  • Changed $.datepicker.disableFor(control) to $(selector).disableDatepicker().
  • Changed $.datepicker.isDisabled(control) to $(selector).isDisabledDatepicker().
  • Changed $.datepicker.reconfigureFor(control, settings) to $(selector).changeDatepicker(settings).
  • Changed $.datepicker.setDateFor(control, date) to $(selector).setDatepickerDate(date).
  • Changed $.datepicker.getDateFor(control) to $(selector).getDatepickerDate().
  • Changed $.datepicker.showFor(control) to $(selector).showDatepicker().
  • Added $(selector).removeDatepicker.
  • Updated compatibility file to reflect changes to core functions.

Так же изменились названия некоторых атрибутов.

Пришлось покопаться с расширением Dialog. В данной версии не работает возможность перемещения окна, а так же если попытаться сделать окно модальным — то, скрипт будет выдавать ошибку. Расширение капризничало в Opera и IE. Оказалось, что виновата строка, где переменные определены следующим образом:

var var1 = f1(), var2 = f2(), var3 = var4 = f3()

Вот там, где инициализируются одновременно две переменные, и было проблемное место.

Ручками доработал скрипт, что бы z-index окна не изменялся при клике по нему. Из-за такой реализации некорректно ведет себя следующий алгоритм. В вызываемом окне используется объект Datepicker, и при клике по окну календарь накрывался окном. Как отключить эффект всплывающего события пока не додумался, а найденное решение меня вполне устраивает.

Сам jQuery немного поправился, упакованная версия весит на 1кБ больше, чем версия 1.2.3. А, вот jQuery UI более заметно прибавил в весе. Субъективно jQuery UI стал пошустрее.

Если кто не обновлялся с первых бет, то рекомендую подождать, как я понял совсем скоро грядёт первый RC, где будут исправлены баги, в том числе и те, что я озвучил в заметке.

Февраль 22, 2007

Firebug не одинок. Инструменты отладки веб-программиста

Filed under: AJAX,CSS,DOM,Броузеры,Ссылки,HTML,JavaScript — 4matic @ 12:10 дп

Последнее время очень много приходится заниматься отладкой скриптов на клиенте. До недавнего времени в этом мне помогал только Firefox с расширением Firebug.

Мне очень нравится работать с Firebug`ом. Что-то лучшее сложно придумать. DOM с полной раскладкой всех атрибутов элементов страницы: можно проследить наследование атрибутов стилей и родственные связи, возможно просматривать информацию, которой обменивается клиент север при работе с AJAX. Так же есть возможность пошаговой отладки JS. Мне очень нравится возможность редактирования страницы прямо в броузере. Да еще много чего — нужно просто установить и получать удовольствие от пользования.

Не так давно «проснулась» Opera. В очередной недельной сборке, а точнее, начиная с версии 9.2 в броузере появился инструмент Developer Console. Аналог FireBug, но только для Opera, но функционал скуднее. Этим инструментом еще толком не пользовался, поэтому что-то внятно-сравнительное не могу сказать.

Немного погугилив нашел похожий инструмент и для IE. Называется этот инструмент Internet Explorer Developer Toolbar. Фукнционал крайне аскетичен и проигрует Opera, но это лучше, чем конь в ваккууме.

Что еще полезно и чем пользуюсь:

  • ieHTTPHeaders — надстройки для IE. Позволяет просматривать заголовки, которыми обменивается клиент с сервером при получении страницы или XMLHttpRequest.
  • LiveHTTPHeaders — расширение для Mozilla, аналогичное по функционалу ieHTTPHeaders.
  • Web Developer Extension — расширение для Mozilla, которое помогает получить детальное представление о странице.
  • Font Finder — расширение для Mozilla, с помощью которого можно получить список атрибутов CSS выделенного фрагмента.
  • HTML VALIDATOR (based on Tidy and OpenSP) — расширение для Mozilla, которое позволяет проверять валидность сверстанных страниц.
  • FirePHP — пока что для меня темная лошадка. Буквально на днях нашел и повода познакомиться ближе не было. Привык работать связкой <pre> + var_dump() + exit().

Пожалуй — это все, что бывает у меня в руках при отладке программ на клиенте.

Декабрь 22, 2006

У атрибутов id и name общее пространство имен в Opera`е и IE`е

Filed under: DOM,Броузеры,Глюки,HTML,JavaScript — 4matic @ 12:28 дп

Представим ситуацию. У вас сложная форма с достаточно большим количеством элементов. Для доступа к некоторым элементам в скрипте вы используете тривиальную конструкцию document.getElementById(). К своему удивлению вы обнаруживаете, что атрибуты объекта отличаются от тех, которые вы ожидаете увидеть. Возможно причина в том, что у вас совпадают значения атрибута id одного объекта и атрибута name другого объекта. Пример:

<input type=»text» name=»test» id=»bad_id»>
<input type=»button» id=»test» onclick=’alert(document.getElementById(«test»).id)’>

Так вот, если мы кликнем по кнопке, то должны получить сообщение «test». НО. Вы получите ожидаемый результат только в Firefox, а вот в Opera и IE вы получите неожиданный результат в виде сообщения «id_test».

Согласно документации getElementById() возвращает первый найденный объект с искомым id. Согласно той же документации id должен быть уникальным, а вот name может повторяться.

В примере мы делаем все правильно и получаем некорректный результат. Скорее всего проблема в том, что в Opera и IE для name и id отведено общее пространство имён. А этого быть не должно. Немного погугилив я нашёл достаточно большое количество ссылок по озвученному вопросу. Показательными я считаю вот эти две:

  1. document.getElementById() returns element with name equal to id specified
  2. Element Name vs Id

Пойдя по первой ссылке мы увидим, что о баге известно уже больше года. Пойдя по второй ссылке мы получим трактование и описание аналогичное моему.

Как решить проблему?

Очень просто. Давать атрибутам id и name логичные значения. Ситуации, когда два разных объекта могут называться одинаково нужно еще поискать.

Если с логикой туго, то давать всем объектам уникальные id и name, уникальные в общем пространстве имен.

А еще лучше разработчикам браузеров устранить баг.

P.S. Нужно будет поэксперементировать с js-фреймворками.

Декабрь 18, 2006

Как удалить узел (node) DOM, зная его id

Filed under: DOM,JavaScript — 4matic @ 4:48 пп

На самом деле все просто. Достаточно знать, какие функции есть для работы с узлами, а так же немного понимать древовидную структуру объектной модели документа (DOM). Если у вас есть озвученные выше знания, то вы напишете следующую функцию, состоящую из одной строки:

function f(idname)
{
document.getElementById(idname).parentNode.removeChild(document.getElementById(idname));
}

Это все :-). Замечу, что в метод родителя removeChild вы должны передавать не идентификатор объекта, а сам объект.

Ссылка по теме:
1. DOM:element.parentNode
2. DOM:element.removeChild

Сентябрь 18, 2006

Как удалить элемент массива в JavaScript?

Filed under: JavaScript — 4matic @ 7:39 пп

Тема массивов в JS — это отдельная тема. Сегодня «узнал» как удалить искомый элемент массива. Все оказалось не так просто. При определенных вариантах решениях этой задачи могут возникнуть грабли. Для удаления элемента массива нужно знать имя элемента массива. А так же нужно знать о существовании метода splice() или оператора delete.

Начнем с splice(), а delete оставим на закуску. Метод splice() — это стандартный метод, т.е. он указан в стандартной спецификации ECMA. Не смотря на это, есть замечания по поводу поддержки этого метода различными браузерами. Так же я не буду описывать сигнатуру метода. Кому интересно пусть RTFM. Смысл функции в том, что бы заменить значения в перечисленных элементах массива на новые значения, если не будут указаны новые значения, то указанные элементы массива просто удалить. Все до безобразия просто, как долото.

Что касается оператора delete. Этот оператор тоже стандартный. Кому нужны подробности — RTFM. Оператор удаляет свойства объекта. Что касается массивов, то здесь нас ждут грабли. Оператор delete удалит элемент массива, но не обновит значение свойства length искомого массива. Перебирая все элементы массива классическим циклом for(i=0;i<n;i++), вы выполните одну лишнюю итерацию, которая при определенных обстоятельствах может вызвать ошибку, которую будет тяжело сходу найти.

На закуску код, написанный на коленке, для деомнстрации описанного выше:

<SCRIPT language="JavaScript"> <!-- var a = new Array(); a[10] = [1, 2, 3]; function showDel() { n = a[10].length; alert('length = ' + n); for (i = 0; i<n; i++) { alert('i = ' + i + ' val = ' + a[10][i]); } a[10].splice(1, 1); n = a[10].length; alert('length = ' + n); for (i = 0; i<n; i++) { alert('i = ' + i + ' val = ' + a[10][i]); } a[10].push(a[10].length + 1); n = a[10].length; alert('length = ' + n); for (i = 0; i<n; i++) { alert('i = ' + i + ' val = ' + a[10][i]); } delete a[10][1]; n = a[10].length; alert('length = ' + n); for (i = 0; i<n; i++) { alert('i = ' + i + ' val = ' + a[10][i]); } } //--> </SCRIPT> <INPUT onclick="showDel()" type="reset" value="Сброс">

Сентябрь 2, 2006

В FF нет метода click() для INPUT type=»file»

Filed under: Броузеры,Глюки,Ссылки,HTML,JavaScript — 4matic @ 12:18 пп

Если вы захотите стилизовать кнопку вызова с обзором файла на локальной машине, т.е. стилизовать элемент управления <INPUT type=»file»>, то у Вас это получится не во всех браузерах. А точнее — это не получится в Лисе (проверено на версии 1.5.0.6).

Я прогугилил варианты решения и ничего толкового не нашел. Хотя ощущается оригинальность решений. Выделить можно два.

О первом варианте вы можете получить представление на странице http://www.quirksmode.org/dom/inputfile.html Я бы назвал это решение: «Если очень нужно, то можно уже и как-нибудь». Принцип сводится к тому, что используется полная прозрачность тега INPUT который накладывается поверх дизайнерского решения. Если вы попробуете решение, а потом попробуете что-то изменить ручками в строке с адресом, то вы увидите, как все запущенно. Другими словами решать задачу на уровне представления нереально по одной причине — у каждого браузера свое представление тега <INPUT type=»file»> — говоря простым языком размеры поля ввода и кнопки могут быть разными большими/маленькими/узкими/толстыми и т.д. все зависит от операционной системы и ее настроек. В общем, если Ваш заказчик сайта топотит ногами, ничего не хочет слушать и с пеной у рта требует стилизовать стандартную кнопку — то используйте вариант, предложенный по ссылке. А когда будете показывать клиенту работу, то меняйте значение в поле только кликами мышки по кнопке «Обзор».

Второй вариант пришел сразу же мне на ум, как только я услышал о проблеме. Думаю, что вы тоже о нем сразу подумали:

<INPUT TYPE=»file» id=»filo» style=»display:none»>
<INPUT TYPE=»button» value=»Любой объект HTML, поддерживающий событие onclick()» onclick=»javascript: document.getElementById(‘filo’).click()»>

Да, решение простое, как долото. НО, это решение не работает в Лисе. Опять моя «любимая» Лиса! Я пошел на форум Мозиллы и задал вопрос. И получил ответы, из которых можно сделать выводы:

  1. Я не там искал. Я искал ответ в спецификации языка HTML, а нужно было искать в спецификации DOM, потому что эмуляция события onclick() происходит с помощью метода объекта. Так вот в спецификации по моему вопросу указано следующее:

    click
    Simulate a mouse-click. For INPUT elements whose type attribute has one of the following values: «button», «checkbox», «radio», «reset», or «submit».

    Т.е. о «file» ничего не сказано. Так же ничего не сказано об типе «image», но в Лисе тег с этим типом имеет метод click().

  2. Судя по ответам я подумал, что ситуация по моему вопросу в ближайшее время не изменится. Потому что озвученное мной решение по какой-то непонятной причине считается небезопасным. В чем опасность я так и не понял, а мне никто не объяснил. (Может, кто-то знает и молчит? Признавайтесь!!!). На форуме Мозиллы мой топик перенесли в раздел «Разработка» (что это значит — я не знаю, на форуме толком смысл этого раздела не описан — остается только догадываться).

Озвучу мысли:

  1. Нужно разделять объектную модель (элементы со свойствами и методами) и представление документа средставми языка разметки.
  2. Получается так, что остальные производители броузеров плохо разбираются в безопасности и дали доступ в своих броузерах к огромнейшей дыре, через которую можно напакостить клиенту. А то что дизайн с таким элементом управления может оказаться убогим, так это мелочь.

Я к своему неприятному удивлению обнаружил, что у меня нет локальной копии спецификации по DOM. Я нашел и скачал ее, теперь буду обязательно пользоваться. Вообщем, поживем — увидим. Надеюсь, что здравый смысл победит паранойю и всем будет счастье.

Ссылки по теме:

  1. Document Object Model (DOM) Level 2 HTML Specification (Архив ZIP для скачивания)
  2. Document Object Model (DOM) Level 2 HTML Specification (on-line спецификация)

Август 10, 2006

onchange и onclick в Опере, ИЕ, Лисе

Filed under: Броузеры,Глюки,JavaScript — 4matic @ 3:45 пп

Как обычно порадовали DOMа. Работаю с элементами checkbox:

var tcb=0;//кол-во чекбоксов c true (глобальная)
function c(obj)
{
   if (obj.checked)
   {
      tcb++;
   }
   else
   {
      tcb--;
   }
   if (nr == tcb) 
   { 
      document.getElementById('allcb').checked = true; 
   } 
   else 
   { 
       if (0 == tcb) 
       { 
          document.getElementById('allcb').checked = false; 
       } 
   }
}

Так вот, событие onchange() для данного объекта есть в Лисе и Опере. В ИЕ данного события для объекта типа нет. Вернее что-то есть, но событием назвать это сложно.

Броузер иногда отрабатывает функцию-обработчик события. Да-да именно иногда, т.е. какого-то четкого поведения мною обнаружено не было. Причину такого поведения — я объяснить не могу.

Решение проблемы — перейти на событие onclick(), которое отлично работает во всех трех клиентах.

Версии клиентов: Opera 9.01, FF 1.5.06, IE6. Windows XP SP2

Блог на WordPress.com.