Шаблоны, препроцессоры, jQuery

Автор учебного курса: Медведский Максим Константинович, студент гр. ИТб-401 ФГАОУ ВО «РГППУ.

Скачать Notepad++ Portable
Скачать Sublime Text 3 Portable
Скачать материалы к учебному курсу -
папка kurs_prepros.zip (2,5 Мб)




Теория 3. Document Object Model

Цель: изучить понятие DOM-дерева, изучить jQuery

Задачи:

  • узнать, что такое DOM-дерево;
  • узнать для чего нужно понимание DOM-дерева;
  • узнать, что такое jQuery;
  • узнать, как работает jQuery.
Рисунок 3.1
Основным инструментом работы и динамических изменений на странице является DOM (Document Object Model) - объектная модель, используемая для XML/HTML-документов.

В DOM страницы представляются в виде иерархического дерева элементов. Каждый листок этого дерева называется узлом и непосредственно связан с каким-то элементом страницы. Узлы, расположенные снизу называются дочерними по отношению к вышестоящим.

Каждый HTML-тег образует отдельный узел, каждый фрагмент текста - текстовый элемент, и т.п.

Простейший DOM

Построим, для начала, дерево DOM для следующего документа

Пример HTML документа

<html>
  <head>
    <title>Заголовок</title>
  </head>
  <body>
     Прекрасный документ
  </body>
</html>

Самый внешний тег - <html>, поэтому дерево начинает расти от него.

Внутри <html> находятся два узла: <head> и <body> - они становятся дочерними узлами для <html>.

Рисунок 3.2

Теги образуют узлы-элементы (element node). Текст представлен текстовыми узлами (text node). И то и другое - равноправные узлы дерева DOM.

Рассмотрим теперь более жизненную страничку.

Пример HTML документа

<html>
    <head>
        <title>
            Mobile OS
        </title>
    </head>
    <body>
          Some mobile OS.
        <ol>
           <li>
               Android
           </li>
           <li>
               iOS
           </li>
           <li>
               Windows Phone
           </li>
        </ol>
    </body>
</html>

Корневым элементом иерархии является html. У него есть два потомка. Первый - head, второй - body. И так далее, каждый вложенный тег является потомком тега выше:

Рисунок 3.3

На этом рисунке синим цветом обозначены элементы-узлы, черным - текстовые элементы.

Дерево образовано за счет синих элементов-узлов - тегов HTML.

А вот так выглядит дерево, если изобразить его прямо на HTML-страничке:

Рисунок 3.4

Рассмотрим чуть более сложный документ.

Пример HTML документа

<html>
    <head>
        <title>Документ</title>
    </head>
    <body>
        <div id="dataKeeper">Data</div>
        <ul>
            <li style="background-color:red">Осторожно</li>
            <li class="info">Информация</li>
        </ul>
        <div id="footer">Made in Russia &copy;</div>
    </body>
</html>

Верхний тег - html, у него дети head и body, и так далее. Получается дерево тегов:

Рисунок 3.5

Атрибуты

В этом примере у узлов есть атрибуты: style, class, id. Вообще говоря, атрибуты тоже считаются узлами в DOM-модели, родителем которых является элемент DOM, у которого они указаны.

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

Возможности, которые дает DOM

Каждый DOM-элемент является объектом и предоставляет свойства для манипуляции своим содержимым, для доступа к родителям и потомкам.

Для манипуляций с DOM используется объект document.

Используя document, можно получать нужный элемент дерева и менять его содержание.

Например, этот код получает первый элемент с тэгом ol, последовательно удаляет два элемента списка и затем добавляет их в обратном порядке:

Пример JavaScript кода

var ol = document.getElementsByTagName('ol')[0]
var android = ol.removeChild(ol.firstChild)
var ios = ol.removeChild(ol.firstChild)
var windows = ol.removeChild(ol.firstChild)
ol.appendChild(windows)
ol.appendChild(ios)
ol.appendChild(android)

Разберем подробнее способы доступа и свойства элементов DOM.

Доступ к элементам

Любой доступ и изменения DOM берут свое начало от объекта document.

Начнем с вершины дерева.

document.documentElement - Самый верхний тег. В случае корректной HTML-страницы, это будет <html>.

document.body - Тег <body>, если есть в документе (обязан быть).

Следующий пример при нажатии на кнопку выдаст текстовое представление объектов document.documentElement и document.body. Сама строка зависит от браузера, хотя объекты везде одни и те же.

Пример доступа к элементам

<html>
  <body>
     <script>
       function go() {
         alert(document.documentElement)
         alert(document.body)
      }
     </script>
     <input type="button" onclick="go()" value="Go"/>
  </body>
</html>

Типы DOM-элементов

У каждого элемента в DOM-модели есть тип. Его номер хранится в атрибуте elem.nodeType

Всего в DOM различают 12 типов элементов.

Обычно используется только один: Node.ELEMENT_NODE, номер которого равен 1. Элементам этого типа соответствуют HTML-теги.

Иногда полезен еще тип Node.TEXT_NODE, который равен 3. Это текстовые элементы.

Остальные типы в javascript программировании не используются.

Следующий пример при нажатии на кнопку выведет типы document.documentElement, а затем тип последнего потомка узла document.body. Им является текстовый узел.

Пример доступа к элементам

<html>
  <body>
     <script>
       function go() {
         alert(document.documentElement.nodeType)
         alert(document.body.lastChild.nodeType)        
      }
     </script>
     <input type="button" onclick="go()" value="Go"/>
     Текст
  </body>
</html>

Например, вот так выглядел бы в браузере документ из примера выше, если каждый видимый элемент обвести рамкой с цифрой nodeType в правом верхнем углу.

Пример HTML кода

<html>
    <head><title>...</title></head>
    <body>
        <div id="dataKeeper">Data</div>
        <ul>
            <li style="background-color:red">Осторожно</li>
            <li class="info">Информация</li>
        </ul>
        <div id="footer">Made in Russia &copy;</div>
    </body>
</html>
Рисунок 3.6

Дочерние элементы

С вершины дерева можно пойти дальше вниз. Для этого каждый DOM-узел содержит массив всех детей, отдельно - ссылки на первого и последнего ребенка и еще ряд полезных свойств.

Свойство 1: Все дочерние элементы, включая текстовые, находятся в массиве childNodes.

Свойство 2: Свойства firstChild и lastChild показывают на первый и последний дочерние элементы и равны null, если детей нет.

Свойство 3: Свойство parentNode указывает на родителя. Например, для <body> таким элементом является <html>.

Свойство 4: Свойства previousSibling и nextSibling указывают на левого и правого братьев узла.

В общем, если взять отдельно <body> с детьми из нормализованного DOM - такая картинка получается от тега <body>:

Рисунок 3.7

И такая - для ссылок наверх и между узлами:

Рисунок 3.8
  • синяя линия - массив childNodes;
  • зеленые линии - свойства firstChild, lastChild;
  • красная линия - свойство parentNode;
  • бордовая и лавандовая линии внизу - previousSibling, nextSibling.

Свойства элементов

У DOM-элементов есть масса свойств. Обычно используется максимум треть из них. Некоторые из них можно читать и устанавливать, другие - только читать.

Рассмотрим здесь еще некоторые свойства элементов, полезные при работе с DOM.

tagName

Атрибут есть у элементов-тегов и содержит имя тега в верхнем регистре, только для чтения. Например:

alert(document.body.tagName) // => BODY

style

Это свойство управляет стилем. Оно аналогично установке стиля в CSS.

Например, можно установить element.style.width:

Пример кода

<input
  type="button"
  style="width: 300px"
  onclick="this.style.width = parseInt(this.style.width)-10+'px'"
  value="Укоротить на 10px"
/>
Обработчик события onclick обращается в этом примере к свойству this.style.width, т.к значением this в обработчике события является текущий элемент (т.е сама кнопка).

className

Это свойство задает класс элемента. Оно полностью аналогично html-атрибуту "class".

elem.className = 'newclass'

onclick, onkeypress, onfocus и другие свойства, начинающиеся на "on...", хранят функции-обработчики соответствующих событий.

Например, можно присвоить обработчик события onclick.

Свойства DOM-элементов

Узел DOM — это объект, поэтому, как и любой объект в JavaScript, он может содержать пользовательские свойства и методы. Поэтому любому узлу можно назначить свойство, используя обычный синтаксис.

Пример кода

var elem = document.getElementById('MyElement')
elem.mySuperProperty = 5
Значением свойства может быть любой объект.
elem.master = {
  name: petya
}

Пользовательские DOM-свойства:

  • могут иметь любое значение;
  • работают за счет того, что DOM-узлы являются объектами JavaScript;
  • названия свойств чувствительны к регистру.

DOM-Атрибуты

Элементам DOM, соответствуют HTML-теги, у которых есть текстовые атрибуты.

В следующем примере элемент имеет атрибуты id, class и нестандартный атрибут alpha.

<div id="MyElement" class="big" alpha="omega"></div>

  • setAttribute(name, value) – Устанавливает значение атрибута. Атрибуты можно добавлять, удалять и изменять;
  • getAttribute(name) – Получить значение атрибута;
  • hasAttribute(name) – Проверить, есть ли такой атрибут;
  • removeAttribute(name) – Удалить атрибут.

Эти методы работают со значением, которое находится в HTML.

Имя атрибута является регистронезависимым.

jQuery

jQuery — библиотека JavaScript, фокусирующаяся на взаимодействии JavaScript и HTML. Библиотека jQuery помогает легко получать доступ к любому элементу DOM, обращаться к атрибутам и содержимому элементов DOM, манипулировать ими.

Библиотека jQuery создана и выпущена Джоном Резигом в январе 2006 года. Она распространяет применение CSS-селекторов для согласования с содержимым модели DOM. Помимо прочих функциональных возможностей, она предоставляет средства для манипулирования моделью DOM, обработки Ajax запросов и событий, а также анимации.

В настоящее время эта библиотека является самой распространенной среди всех библиотек JavaScript.

Начнем сразу с интересного, хоть и непрактичного примера. Нам необходимо раскрасить таблицу в таком стиле:

Рисунок 3.9

Предполагается, что у нас есть CSS-файл, в котором определен класс «odd». Все, что нам нужно сделать, – это наделить нечетные строки в таблице эти классом.

Пример кода

JavaScript:
var tables = document.getElementsByTagName("table");
for ( var t = 0; t < tables.length; t++ ) {
  var rows = tables[t].getElementsByTagName("tr");
  for ( var i = 1; i < rows.length; i += 2 )
    if ( !/(^|s)odd(s|$)/.test( rows[i].className ) )
      rows[i].className += " odd";
}

jQuery:
$("tr:nth-child(odd)").addClass("odd");

Как видно из этого примера, библиотека jQuery позволяет находить простые и изящные решения для, казалось бы, сложных задач.

Принцип работы jQuery

Основным отличием jQuery от других библиотек является то, что можно применять некие действия не только к отдельному элементу, но и к коллекции в целом. Т.е. достаточно выделить нужную коллекцию элементов и применить к ней требуемые действия.

Ключом к пониманию работы jQuery является функция $(). Эта функция, так или иначе, вызывается всеми методами jQuery. Вне зависимости от параметров, переданных в функцию, знак доллара вернет список объектов, над которым уже определены все доступные jQuery-функции. Это позволяет работать с любыми объектами – уже существующими на странице, созданными динамически – так, как будто это одни и те же элементы, уже существующие на странице.

Суть jQuery в том, чтобы отбирать элементы HTML-страниц и выполнять над ними некоторые операции.

С введением CSS в веб-технологии для отделения представления от содержимого понадобился способ, позволяющий ссылаться на группы элементов страницы из внешних таблиц стилей. В результате был разработан метод, основанный на использовании селекторов. Библиотека jQuery использует те же самые селекторы.

Синтаксис отбора группы элементов прост:

$(selector) или jQuery(selector)

 
Функция $() (псевдоним функции jQuery()) возвращает специальный объект JS, который содержит массив элементов DOM, соответствующих указанному селектору.

На языке программирования такого рода конструкция называется обёрткой (wrapper), потому что она обёртывает отобранные элементы дополнительной функциональностью. Мы будем использовать термин обёртка jQuery, или обёрнутый набор, ссылаясь на группы элементов, управлять которыми позволяют методы, определённые в jQuery.

Предположим, нам требуется реализовать постепенное исчезновение всех элементов <div>. jQuery позволяет сделать это так:

$("div").fadeOut();

Особенностью многих из этих методов состоит в том, что по завершении своих действий они возвращают ту же самую группу элементов, готовую к выполнению другой операции. Предположим, что после исчезновения к элементам нужно добавить класс CSS removed. Записать это можно так:

$("div").fadeOut().addClass(“removed”);

Такую цепочку (chain) команд jQuery можно продолжать до бесконечности. В интернете можно без труда отыскать примеры цепочек jQuery, состоящих из десятков команд.

Несмотря на то, что группа отобранных элементов представлена довольно сложным объектом JS, в случае необходимости мы можем обращаться к ней как к обычному массиву элементов. В итоге следующие две инструкции дают идентичные результаты:

$("#somediv").html("let's add some text!"); $("#somediv")[0].innerHTML = "let's add some text!";

Поскольку здесь используется селектор по атрибуту ID, ему будет соответствовать один элемент. В первом случае используется метод библиотеки jQuery – html(), который замещает содержимое элемента DOM некоторой HTML-разметкой. Во втором случае с помощью jQuery извлекается массив элементов, выбирается первый элемент массива с индексом 0 и затем его содержимое замещается с помощью самого обычного метода JS.

Тот же результат можно получить с помощью селектора, который может отобрать несколько элементов:

Пример кода

$("div").html("let's add some text!");
или
var elements = $("div");
for (i=0; i<elements.length; i++)
  elements[i].innerHTML = "let's add some text!";

Подробнее о различных функциях jQuery можно прочитать в документации jQuery API.

Контрольные вопросы

  1. Что такое DOM-дерево?
  2. Что такое узел DOM?
  3. Как можно определять тип для произвольного узла?
  4. Что является корневым элементом любой иерархии?
  5. Являются ли атрибуты DOM-узлами?
  6. Что используется для манипуляции DOM?
  7. Что возвращает свойство lastChild?
  8. Что возвращает свойство parentNode?
  9. Что имеет атрибут tagName?
  10. Что такое jQuery?
  11. Что означает $()?
  12. Что возвращает функция $()?
  13. Что делает данная строка?
    $("div").fadeOut();
  14. Что делает метод html()?
  15. Какая максимальная длина цепочки вызовов(chain)?