Книга: JavaScript. Подробное руководство, 6-е издание

15.2.3. Выбор элементов по типу

15.2.3. Выбор элементов по типу

Метод getElementsByTagName() объекта Document позволяет выбрать все HTML- или XML-элементы указанного типа (или по имени тега). Например, получить подобный массиву объект, доступный только для чтения, содержащий объекты Element всех элементов <span> в документе, можно следующим образом:

var spans = document.getElementsByTagName("span");

Подобно методу getElementsByName(), getElementsByTagName() возвращает объект NodeList. (Подробнее класс NodeList описывается во врезке, в этом же разделе.) Элементы документа включаются в массив NodeList в том же порядке, в каком они следуют в документе, т. е. первый элемент <р> в документе можно выбрать так:

var firstpara = document.getElementsByTagName("p")[0];

Имена HTML-тегов не чувствительны к регистру символов, и когда getElementsByTagName() применяется к HTML-документу, он выполняет сравнение с именем тега без учета регистра символов. Переменная spans, созданная выше, например, будет включать также все элементы <span>, которые записаны как <SPAN>.

Можно получить NodeList, содержащий все элементы документа, если передать методу getElementsByTagName() шаблонный символ «*».

Кроме того, классом Element также определяет метод getElementsByTagName(). Он действует точно так же, как и версия метода в классе Document, но выбирает только элементы, являющиеся потомками для элемента, относительно которого вызывается метод. То есть отыскать все элементы <span> внутри первого элемента <р> можно следующим образом:

var firstpara = document.getElementsByTagName("p")[0];
var firstParaSpans = firstpara.getElementsByTagName("span");

По историческим причинам класс HTMLDocument определяет специальные свойства для доступа к узлам определенных типов. Свойства images, forms и links, например, ссылаются на объекты, которые ведут себя как массивы, доступные только для чтения, содержащие элементы <img>, <form> и <а> (но только те теги <а>, которые имеют атрибут href). Эти свойства ссылаются на объекты HTMLCollection, которые во многом похожи на объекты NodeList, но дополнительно могут индексироваться значениями атрибутов id и name. Ранее мы узнали, как можно получить ссылку на именованный элемент <form> с помощью такого выражения:

document.shipping_address

С помощью свойства document.forms обращение к форме, имеющей атрибут name (или id), можно записать более явно:

document.fоrms.shipping_address;

Объект HTMLDocument также определяет свойства-синонимы embeds и plugins, являющиеся коллекциями HTMLCollection элементов <embed>. Свойство anchors является нестандартным, но с его помощью можно получить доступ к элементам <а>, имеющим атрибут name, но не имеющим атрибут href. Свойство scripts определено стандартом HTML5 и является коллекцией HTMLCollection элементов <script>, но к моменту написания этих строк оно было реализовано не во всех броузерах.

Кроме того, объект HTMLDocument определяет два свойства, каждое из которых ссылается не на коллекцию, а на единственный элемент. Свойство document.body представляет элемент <body> HTML-документа, а свойство document.head - элемент <head>. Эти свойства всегда определены в документе: даже если в исходном документе отсутствуют элементы <head> и <body>, броузер создаст их неявно. Свойство document.Element объекта Document ссылается на корневой элемент документа. В HTML-документах он всегда представляет элемент <html>.

Объекты NodeList и HTMLCollection

Методы getElementsByName() и getElementsByTagName() возвращают объекты NodeList, а такие свойства, как document.images и document.forms, являются объектамиHTMLCollection.

Эти объекты являются объектами, подобными массивам, доступным только для чтения (раздел 7.11). Они имеют свойство length и могут индексироваться (только для чтения) подобно настоящим массивам. Содержимое объекта NodeList или HTMLCollection можно обойти с помощью стандартного цикла, например:

for(var і = 0; і < document.images.length; i++) // Обойти все изобр.
  document.images[і].style.display = "none"; // ...и скрыть их.

Для объектов NodeList и HTMLCollection нельзя непосредственно вызывать методы класса Array, но их можно вызывать косвенно:

var content = Array.prototype.mар.call(
          document.getElementsByTagName("p"),
          function(e) { return e.innerHTML; });

Объекты HTMLCollection могут иметь дополнительные именованные свойства и могут индексироваться не только числами, но и строками.

По историческим причинам оба объекта, NodeList и HTMLCollection, могут также играть роль функций: вызов их с числовым или строковым аргументом равносилен операции индексирования числом или строкой. Однако использование этой причудливой особенности может сбивать с толку.

Интерфейсы обоих объектов, NodeList и HTMLCollection, проектировались под другие языки программирования, не такие динамические, как JavaScript. Оба определяют метод item(). Он принимает целое число и возвращает элемент с этим индексом. Однако в программах на языке JavaScript нет нужды использовать этот метод, так как можно использовать простую операцию индексирования массива. Аналогично HTMLCollection определяет метод namedltem(), возвращающий значение именованного свойства, но в программах на языке JavaScript вместо него можно использовать операции индексирования массива и обращения к свойствам.

Одна из наиболее важных и интересных особенностей объектов NodeList и HTMLCollection состоит в том, что они не являются статическими слепками документа, а продолжают «жить», и списки элементов, которые они представляют, изменяются по мере изменения документа. Если вызвать метод getElementsByTagName('div') для документа, в котором отсутствуют элементы <div>, он вернет объект NodeList, свойство length которого будет равно 0. Если затем вставить в документ новый элемент <div>, этот элемент автоматически станет членом коллекции NodeList, а ее свойство length станет равно 1.

Обычно такая динамичность элементов NodeList и HTMLCollection бывает весьма полезна. Однако если добавлять или удалять элементы из документа в процессе итераций по коллекции NodeList, потребуется предварительно создать статическую копию объекта NodeList:

var snapshot = Array.prototype.slice.call(nodelist, 0);

****************************************

Оглавление книги


Генерация: 3.523. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз