Отримати елементи за атрибутом, коли 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.