Отримати елементи за атрибутом, коли querySelectorAll недоступний без використання бібліотек?


123
<p data-foo="bar">

Як можна зробити еквівалент

document.querySelectorAll('[data-foo]')

де querySelectorAll це не доступно ?

Мені потрібно рідне рішення, яке працює принаймні в IE7. Мене не хвилює IE6.


огляньте бібліотеку вибору javascript sizzle.js
епоха

1
Приємно, що єдиний вибір, який мені потрібно зробити, - це атрибути даних, тому я намагався зрозуміти найпростіший спосіб виправити це, не затягуючи цілий механізм селектора, як Sizzle. Але хороший момент, щоб подивитися в джерелі. BTW - ще один чудовий селекторний двигун - github.com/ded/qwery
ryanve

@ryanve, дякую, я погляну :)
епоха

Я використовував робоче рішення в github.com/ryanve/dope/blob/master/dope.js у методі під назвою "queryAttr"
ryanve

7
Лол, твоє запитання - моя відповідь. Тож це постає з іншим питанням. У якій ситуації querySelectorAllнемає? note - I don't care all IE
vzhen

Відповіді:


136

Ви можете написати функцію, яка запускає getElementsByTagName ('*') і повертає лише ті елементи з атрибутом "data-foo":

function getAllElementsWithAttribute(attribute)
{
  var matchingElements = [];
  var allElements = document.getElementsByTagName('*');
  for (var i = 0, n = allElements.length; i < n; i++)
  {
    if (allElements[i].getAttribute(attribute) !== null)
    {
      // Element exists with attribute. Add to array.
      matchingElements.push(allElements[i]);
    }
  }
  return matchingElements;
}

Тоді,

getAllElementsWithAttribute('data-foo');

8
Використання != null- це ідеальний спосіб (краще, ніж мій коментар вище), тому що в старому IE можна getAttribute повернути значення, яке typeofє'number'
ryanve

1
Навіщо використовувати document.getElementsByTagName('*')замість document.all?
педрозат

1
Чому б не використовувати, hasAttributeа не getAttribute() !== null, оскільки ви хочете перевірити лише існування, а не його значення?
rvighne

61

Використовуйте

//find first element with "someAttr" attribute
document.querySelector('[someAttr]')

або

//find all elements with "someAttr" attribute
document.querySelectorAll('[someAttr]') 

знайти елементи за атрибутом. Зараз він підтримується у всіх відповідних браузерах (навіть IE8): http://caniuse.com/#search=queryselector


2
Як це має стільки обґрунтованих результатів, коли питання прямо запитує: "Мені потрібно нативне рішення, яке працює принаймні в IE7 ". По- друге, що посилання заявляє , що починає підтримку в IE11 , навіть якщо він на справді починається з IE8 - може бути , це повинно бути вивантажено на developer.mozilla.org/en-US/docs/Web/API/Element / ... так це на самому справі підтримує відповідь. ..?
Zze

7
Причина всіх оновлень і причина, коли я зробив відповідь, полягає в тому, що це питання справді старе, тому, коли ви шукаєте, як знайти елементи DOM, ви вважаєте це запитання дуже високим в результатах пошуку, і оскільки це те, що люди шукають, як вони підняли. Корисність> історична точність. По-друге, посилання все ще працює чудово, це просто те, що caniuse.com має приховані старі браузери, якщо перейти на "Використання відносно", ви все одно побачите старі браузери.
Pylinux

Працювали чудово. Швидке та просте
Доусон Б

Це 2020 рік. Це має бути прийнятою відповіддю зараз.
ПоблизуГускарля

44

Я трохи пограв і закінчив це сире рішення:

function getElementsByAttribute(attribute, context) {
  var nodeList = (context || document).getElementsByTagName('*');
  var nodeArray = [];
  var iterator = 0;
  var node = null;

  while (node = nodeList[iterator++]) {
    if (node.hasAttribute(attribute)) nodeArray.push(node);
  }

  return nodeArray;
}

Використання досить просте і працює навіть в IE8:

getElementsByAttribute('data-foo');
// or with parentNode
getElementsByAttribute('data-foo', document);

http://fiddle.jshell.net/9xaxf6jr/

Але я рекомендую використовувати querySelector/ Allдля цього (а також для підтримки старих браузерів використовувати polyfill ):

document.querySelectorAll('[data-foo]');

Так, +1 для запитуSelectorAll. Швидкий тест на jsperf jsperf.com/custom-vs-selectorall-attributes показує, що це набагато швидше, ніж прийнята відповідь ... на жаль, це не сумісне з IE 7 :(
Sebastien Daniel

11

Спробуйте це працює

document.querySelector ('[attribute = "value"]')

приклад:

document.querySelector('[role="button"]')

5

Це теж працює:

document.querySelector([attribute="value"]);

Так:

document.querySelector([data-foo="bar"]);

2
У цьому відсутні відсутні цитати у фактичному querySelector. Повинно бути: document.querySelector('[data-foo="bar"]');
Brettins

1

Спробуйте це - я трохи змінив вищевказані відповіді:

var getAttributes = function(attribute) {
    var allElements = document.getElementsByTagName('*'),
        allElementsLen = allElements.length,
        curElement,
        i,
        results = [];

    for(i = 0; i < allElementsLen; i += 1) {
        curElement = allElements[i];

        if(curElement.getAttribute(attribute)) {
            results.push(curElement);
        }
    }

    return results;
};

Тоді,

getAttributes('data-foo');

3
Що ви змінили і чому?
Artjom B.

1

Трохи модифікація на @kevinfahy «s відповідь , щоб отримувати атрибут , значення , якщо це необхідно:

function getElementsByAttributeValue(attribute, value){
  var matchingElements = [];
  var allElements = document.getElementsByTagName('*');
  for (var i = 0, n = allElements.length; i < n; i++) {
    if (allElements[i].getAttribute(attribute) !== null) {
      if (!value || allElements[i].getAttribute(attribute) == value)
        matchingElements.push(allElements[i]);
    }
  }
  return matchingElements;
}

0

Не використовувати в браузері

У браузері використовуйте document.querySelect('[attribute-name]') .

Але якщо ви перевіряєте блок, і ваш глузливий будинок має нескінченну реалізацію querySelector, це зробить трюк.

Це відповідь @ kevinfahy, просто обрізана, щоб бути трохи з функціями стрілки жиру ES6 і шляхом перетворення HtmlCollection в масив, можливо, ціною читабельності.

Тож він працюватиме лише з транспілером ES6. Крім того, я не впевнений, наскільки це буде виконати багато елементів.

function getElementsWithAttribute(attribute) {
  return [].slice.call(document.getElementsByTagName('*'))
    .filter(elem => elem.getAttribute(attribute) !== null);
}

А ось варіант, який отримає атрибут із конкретним значенням

function getElementsWithAttributeValue(attribute, value) {
  return [].slice.call(document.getElementsByTagName('*'))
    .filter(elem => elem.getAttribute(attribute) === value);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.