Как перебрать все атрибуты в элементе HTML?

Мне нужен код JavaScript для перебора заполненных атрибутов в элементе HTML.

Эта ссылка Element.attributes говорит, что я могу получить к ней доступ через индекс, но не указывает, хорошо ли она поддерживается и может ли она использоваться (кросс-браузер).

Или какими-то другими способами? (без использования каких-либо фреймворков, таких как jQuery / Prototype)

6 ответов

Решение

Это будет работать в IE, Firefox и Chrome (кто-нибудь может протестировать другие, пожалуйста? - Спасибо, @Bryan):

for (var i = 0; i < elem.attributes.length; i++) {
    var attrib = elem.attributes[i];
    console.log(attrib.name + " = " + attrib.value);
}

РЕДАКТИРОВАТЬ: IE перебирает все атрибуты, которые поддерживает рассматриваемый объект DOM, независимо от того, были ли они на самом деле определены в HTML или нет.

Вы должны посмотреть на attrib.specified Логическое свойство, чтобы узнать, существует ли атрибут на самом деле. Firefox и Chrome также поддерживают это свойство:

for (var i = 0; i < elem.attributes.length; i++) {
    var attrib = elem.attributes[i];
    if (attrib.specified) {
        console.log(attrib.name + " = " + attrib.value);
    }
}

Другой метод - преобразовать коллекцию атрибутов в массив, используя Array.from:

Array.from(element.attributes).forEach(attr => {
  // process attr
})

В случае, если кто-то заинтересован в отфильтрованной версии или пытается создать селекторы атрибутов CSS, вот вам:

let el = document.body;
Array.from(el.attributes)
    .filter(a => { return a.specified && a.nodeName !== 'class'; })
    .map(a => { return '[' + a.nodeName + '=' + a.textContent + ']'; })
    .join('');

//outputs: "[name=value][name=value]

Вы, конечно, можете удалить соединение, чтобы получить массив или добавить фильтр для "стиля", поскольку в большинстве веб-приложений тегом стиля широко манипулируют виджеты.

Самый простой подход - использовать оператор спреда.

const el = document.querySelector('div');

[...el.attributes].forEach((attr) => {
  console.log(attr.name + ' = ' + attr.value);
});
<div class="foo" id="bar"></div>

Более эффективным

Array.prototype.forEach.call(elm.attributes, attr => console.log(attr))

Это довольно старый вопрос, но, реагируя на ответ @N-ate, вот версия, следующая тому же подходу функционального программирования, которая возвращает объект JS, ключи которого являются именами атрибутов, а значения являются связанными значениями атрибутов:

      Array.from(element.attributes)
    .filter(a => a.specified)
    .map(a => ({[a.nodeName]: a.nodeValue}))
    .reduce((prev, curr) => Object.assign(prev || {}, curr))

Это получается:

      <div class="thingy verse" id="my-div" style="color: red;"><p>Hello</p></div>

В

      {
    class: "thingy verse",
    id: "my-div",
    style: "color: red;"
}
Другие вопросы по тегам