Лучший способ получить атрибуты от getElementsByTagName ()? - PullRequest
8 голосов
/ 20 сентября 2011

Я играю с получением атрибутов тега link, кажется, есть несколько способов доступа к атрибутам:

document.getElementsByTagName("link")[0]['media']
document.getElementsByTagName("link")[0].media
document.getElementsByTagName("link")[0].getAttribute('media')
document.getElementsByTagName("link")[0].attributes['media']

Это граничит с нелепым количеством путей к одному и тому жеданные.Один из этих методов намного превосходит остальные?

Ответы [ 4 ]

12 голосов
/ 20 сентября 2011

Я бы использовал .media для этого случая, поскольку media действительно является свойством элемента ссылки.Каждый из них имеет свое использование:

  • ['media']: Извлекает значение свойства «media», используя квадратную скобку.Используйте обозначение в квадратных скобках, когда вы не знаете название свойства во время разработки.Например, при итерации свойств.
  • .media: Извлекает значение свойства media.Я бы использовал это в большинстве случаев.Он обеспечивает краткий прямой доступ к значению свойства.
  • .getAttribute('media'): Извлекает значение атрибута «media».Используйте это, когда вы хотите значение атрибута, который не обязательно является свойством элемента.Не все атрибуты являются свойствами, а не все свойства являются атрибутами.
  • .attributes['media']: Извлекает узел атрибута «media».Используйте коллекцию атрибутов, когда вам нужно больше информации об атрибуте, чем просто о его значении.Например, имя атрибута.Вы также можете легко использовать это для получения значения, так как .toString() возвращает значение, но это может быть излишним, если все, что вам нужно, это значение.Коллекция attributes также полезна для итерации атрибутов элемента .
4 голосов
/ 20 сентября 2011

Метод, который вы ищете, называется getElementsByTagName. Возвращает массив элементов в виде списка (который не является массивом).

Обратите внимание, что ваш последний пример .attributes['media'] не возвращает строку, как другие методы. Вместо этого он возвращает узел атрибута.

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

Чтобы добавить немного больше технических деталей, хотя в большинстве случаев разные способы возвращают одни и те же способы, это не всегда верно для несуществующих атрибутов. В качестве примера возьмем следующий HTML: <a href='test'>. Вы можете попробовать сами в другом браузере на тесте jsFiddle (вывод ниже от Firefox).

// Get reference to element
var a = document.getElementsByTagName('a')[0];

// Existent attributes
console.log(a.href); // String: http://fiddle.jshell.net/_display/test
console.log(a.getAttribute('href')); // String: test
console.log(a.attributes['href']); // Attribute node: href

Обратите внимание, что один раз был возвращен абсолютный URI, в другой раз - оригинальное значение.

// Existent invalid attributes
console.log(a.other); // undefined
console.log(a.getAttribute('other')); // String: thing
console.log(a.attributes['other']); // Attribute node: other

Все, что существует при загрузке страницы, объединяется в DOM, но недоступно как свойство, если недействительно.

// Inexistent but valid attributes
console.log(a.title); // Empty string
console.log(a.getAttribute('title')); // null
console.log(a.attributes['title']); // undefined

Первый вызов вернул значение свойства по умолчанию. Затем мы увидели null как маркер несуществующего атрибута. Наконец, мы получили так называемый NamedNodeMap, который является чем-то вроде смеси массива и объекта. Доступ к нему как к объекту дал значение undefined.

// Creating attributes
a.setAttribute('title', 'test title');
console.log(a.title); // String: test title
console.log(a.getAttribute('title')); // String: test title
console.log(a.attributes['title']); // Attribute node: title

Атрибут также становится доступным как свойство.

// Creating "attributes" by using property
a.rel = 'test rel';
console.log(a.rel); // String: test rel
console.log(a.getAttribute('rel')); // String: test rel
console.log(a.attributes['rel']); // Attribute node: rel

Установка свойства для действительного атрибута также создает запись в attributes map.

// Inexistent invalid attributes
console.log(a.dummyInvention); // undefined
console.log(a.getAttribute('dummyInvention')); // null
console.log(a.attributes['dummyInvention']); // undefined

Доступ к свойству на a, возвращаемое значение маркера и доступ к индексу на карте узла.

// Creating invalid attributes via setAttribute
a.setAttribute('title2', 'test title2');
console.log(a.title2); // undefined
console.log(a.getAttribute('title2')); // String: test title2
console.log(a.attributes['title2']); // Attribute node: title2

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

// Creating invalid "attributes" via property
a.title3 = 'test title3';
console.log(a.title3); // String: test title3
console.log(a.getAttribute('title3')); // null
console.log(a.attributes['title3']); // undefined

Объект a расширен, но DOM нетронут.

// NamedNodeMap of length 4 and indexes other, href, title, rel, title2 (valid attributes or result of setAttribute in order of creation except those from parsing)
console.log(a.attributes);

Карта узлов отражает только текущее состояние DOM. Он не знает о расширении нашего объекта a, который мы получили через getElementsByTagName.

Важно отметить, что манипулирование объектом JavaScript не обязательно влияет на DOM. DOM отражает только те вещи, которые были доступны при разборе и модификации с помощью методов DOM или модификаций свойств (предопределенных свойств). Я надеюсь, что я не пропустил ни одного важного случая и что комментарии были достаточно многословны, чтобы увидеть, что происходит.

Я был бы признателен за комментарий к окончательному NamedNodeMap, потому что я хотел бы знать, корректно ли поведение Firefox, чтобы отбрасывать порядок атрибутов при разборе.

1 голос
/ 20 сентября 2011

Функционально они равны.

По производительности первые два превосходят по значительному фактору, хотя все они чрезвычайно быстры.См. этот тест JSPerf .

На практике первые два легче читать, а мои личные предпочтения - вторые.(Это также волос быстрее.)

0 голосов
/ 20 сентября 2011

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

Последние два варианта зависят от getAttribute() и setAttribute(), которые не всегда были надежны в IE.Вы можете прочитать больше об этом в справке , которую Мэтт опубликовал .Таким образом, я предпочитаю версию .media из всех четырех ваших вариантов выбора как наиболее надежную и удобочитаемую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...