О популярности JavaScript в Википедии слагают легенды. Специалисты объясняют эту популярность в основном простотой языка и широкой поддержкой в прикладных программах. Такой взгляд кажется нам немного поверхностным.
Определяющая причина всего одна – это обыкновенная монополия. Существует одна-единственная широко применяемая программа, которая нуждается в языке сценариев, и эта программа поддерживает один-единственный язык – JavaScript. Программа называется «Браузер»; это название имеет несколько синонимов: «Опера», «Firefox», «Интернет Эксплорер», «Гугл Хром»... Монополия в данном случае не так уж и плоха, она, скорее, создаёт дополнительное удобство – помогает стандартизации.
Простым JavaScript называют, потому что он очень небольшой по объёму – для работы достаточно иметь представление всего о 4-5-ти встроенных объектах (String, Array, Function...) и знать основы синтаксиса (управляющие структуры типа for, if...).
Он невелик по объёму, однако достаточно сложен по своей идеологии (сложнее, например, чем PHP); он коварный и даже противный – можно даже сказать, что это один из самых противных языков программирования; противнее него, пожалуй, только Postscript (тоже заканчивается на -script, но совсем по другой причине).
Простота JavaScript – это иллюзия, возникающая у начинающего HTML-криэйтора, который списал с первого найденного сайта фрагмент кода, вставил на свою первую HTML-страничку, и – ура! – работает!
Да. И самая плохая новость: небольшим по объёму является только ядро JavaScript. Фрагмент кода, списанный юным гением у соседа по парте, чаще всего никакого отношения к ядру языка не имеет: все эти onclick и onmouseover – совсем уже из другой Оперы (или из Firefox'а).
Возьмите навскидку любой кусок JavaScript из любой веб-страницы в сети (например, код счётчика): document.write, screen.height, window.open и ещё сотни выражений, смысл которых нельзя понять из спецификации ядра JavaScript. Эта часть кода в общем-то и не относится к JavaScript: она оперирует понятиями (объектами), описанными в другой спецификации – DOM (Document Object Model). Популярную на многих сайтах о JavaScript фразу «JavaScript НЕ Java!», следовало бы всегда дополнять ещё одной: «DOM НЕ JavaScript!».
Ещё одна плохая новость: браузеры реализуют DOM по-разному, HTML-программисту необходимо знать как минимум три диалекта DOM: для Оперы, Gecko (Firefox) и для Интернет Эксплорера. Тут можно легко заблудиться и утонуть. Именно поэтому, наверное, PHP-программисты так не любят HTML.
Чтобы выплыть, нужен чёткий алгоритм поведения, который в первом приближении можно описать так:
Но наша статья не об этом.
Это огромный массив информации – список объектов, свойств, методов и событий DOM. После некоторого опыта работы вы уже будете примерно представлять, что там есть, и каких подводных камней следует опасаться; будете знать, что вам нужно. Но для точной формулировки выражения где-то надо посмотреть, как оно правильно пишется. Значения («слова»), орфография и синтаксис. Какой, например, nodeType у текста? Как называется вычисленная браузером ширина элемента? Какие события связаны (можно связать) с интересущим вас элементом? Есть ли у него потомки и как их получить? Доступно ли в этом окне свойство document.all? Почему не работает команда "document.body.style.text-align='left'"?
Можно долго добираться до намеченного способа решения по лабиринтам трёхмерной (Опера – Gecko – ИЕ) спецификации. Но можно быстро и легко получить подсказку – список свойств текущего окна браузера или какого-нибудь элемента HTML. С помощью самого JavaScript. Ведь всё в JavaScript – объекты. А у объектов есть свойства. И эти свойства можно просмотреть в просто цикле:
for (var svoistvo in object) { document.write(svoistvo+": "+object[svoistvo]+"<br>"); }
Подставьте в пример вместо object document.body – и получите список для BODY. Подставьте любой другой элемент, полученный программой, например, с помощью метода document.getElemenById(). Разумеется, если вы совершенно не знакомы с DOM, этот список мало чем вам поможет – разве что как отправная точка, как список слов, значение которых надо выучить, обратившись к справочнику HTML-DOM-JavaScript (например, http://infodisk.info/books/lukatch.chm). И, разумеется (как всегда!), указанный простой способ вывода свойств в реальном окне браузера работать не будет (иногда будет, иногда нет).
После небольшой доработки напильником наш простой пример увеличивается в объёме до 3К (dom-javascript.js) и начинает работать с браузерами Opera, Firefox (вообще Gecko), Gogle Chrome, Internet Explorer. Чтобы DOM-инспектор (или, можно сказать, DOM-помощник) начал работать на какой-нибудь HTML-странице, в конец страницы надо поместить код:
<script type='text/javascript' src='dom-javascript.js'></script>
А рядом с данной страницей на сайте (в той же папке) поместить сам скрипт – файл dom-javascript.js. После этого при открытии страницы у неё (у объекта document) по событию onkeyup (нажатие клавиш) будет выскакивать окно сообщений с правилами работы. Клавиши нужно нажимать такие: Ctrl+Alt+1 (или 2, или 3). Цифра в этом случае устанавливает уровень вложенности элементов DOM, которые скрипт будет выводить на экран. Для просмотра сведений об элементе надо щёлкнуть по нему мышкой, удерживая нажатыми клавиши Ctrl и Alt (Ctrl+Alt+Click). Ctrl+Alt+b выведет сведения о BODY, Ctrl+Alt+d – об объекте document. Всё это можно попробовать прямо сейчас, на этой странице. Смело щёлкайте по любому месту на ней, удерживая клавиши Ctrl и Alt.
Подобные помощники существуют в некоторых браузерах. Например, в Gogle Chrome. Раньше DOM инспектор был и в Firefox'е, но в версии 3 его зачем-то удалили (и теперь надо искать и устанавливать специальный плагин). Общая проблема «дерева» свойств DOM – «зацикливание»: например, у элемента DIV есть свойство parentNode (допустим, это элемент BODY). А у элемента BODY есть свойство firstChild – и его значение может оказаться равным нашему элементу DIV. Ну, пусть не firstChild, но у BODY всё равно есть childNodes, и один из элементов этого списка всё равно будет наш DIV. И у него опять-таки есть свойство parentNode. С непривычки очень легко можно запутаться в этих бесконечно вложенных друг в друга свойствах.
Для минимизации этой проблемы у нашего DOM-помощника как раз и вводится (пользователем через диалоговое окно) перед началом работы количество уровней вложенности – от 1 до 3.
Недостаток нашего скрипта: код ветвится на основе определения браузера (проверкой свойства navigator.userAgent). Идеологически правильнее (выдержаннее:-) ветвить код, проверяя существование конкретных свойств и объектов. Но это требует больше усилий и знаний в нашем случае. Мы решили, что оно того (времени) не стоит. Функцию init(), наверное, правильнее приписать событию body onload, а не просто запускать в том месте, где стоит скрипт.
Ряд свойств DOM (типа innerHTML) исключается из показа (в скрипте список stoplist), потому что с ними 3-уровневый список, например, в Опере, вырастает до размера многих мегабайт (может не хватить терпения дожидаться его полного вывода).
При прохождении по циклу свойств объекта for (var p in obj) {} возникли ситуации, когда свойство p находится, а его значение obj[p] недоступно (при обращении к нему возникает ошибка). Нам не настолько интересно вникать в глубины DOM-JavaScript, чтобы разобраться что там к чему, поэтому мы просто добавили в этом случае обработку исключений:
try { val=obj[p]; } catch (e) { val=""; }
При запуске нашего DOM-инспектора информация выскакивает в новом окне. Там можно искать ответы обычным поиском по Ctrl+f. Если поискать слово nodeType, около него будет число – значение свойства nodeType для данного элемента (только следите за уровнем вложенности – какого именно элемента). У каждого элемента вообще есть в свойствах целый список, перечисляющий nodeType всех узлов: # ELEMENT_NODE: 1, # ATTRIBUTE_NODE: 2...
Вычисленная браузером ширина элемента называется offsetWidth. Вы можете точно не знать этого слова, но если примерно представляете ширину элемента в пикселах, ищите близкое по значению число (а слева рядом с ним – название свойства)...
У каждого элемента в списке свойств есть всякие onclick, onbeforeupdate (в ИЕ). У некоторых свойств некоторых объектов (на этой странице – у document или body, в зависимости от браузера) будут заданные пользователем значения. Что-то вроде «onclick: function showprop(e) { if (e.ctrlKey...».
Потомков текущего элемента можно увидеть в списке childNodes (если указать уровень вложенности > 1).
Свойство all можно также поискать в текущем окне свойств. В Интернет Эксплорере оно найдётся (и не один раз), в Firefox'е – нет.
Команда "document.body.style.text-align='left'" написана неправильно. Выражения «text-align», «background-color» правильны в контексте файла CSS (или внутри элемента style в коде страницы). При программном досупе к свойствам DOM эти выражения формулируются несколько по-другому: textAlign, backgroundColor. Список всех доступных выражений можно увидеть во всплывающем окне свойств нашего DOM-помощника, если попытаться получить свойства, например, объекта body (Ctrl+Alt+b) с уровнем вложенности 2. Можно и других элементов внутри body (Ctrl+Alt+щелчком мыши). Ищите в окне свойств слово style.
Исправлен файл http://ir2.ru/static/dom-javascript.js (старая версия: http://ir2.ru/static/dom-javascript0.js). Из обработки кроссбраузерности исключена проверка navigator.userAgent. Идея e = e || window.event легко найдена на сайте http://javascript.ru/ (спасибо Илье Кантору).
В Опере 9.50 обнаружилась проблема: скрипт вывода DOM запускается не по Ctrl+Alt+Click, а почему-то только по Ctrl+Alt+DblClick.