Используя только JavaScript, каков наиболее эффективный способ выбрать все элементы DOM, которые имеют определенный data-
(скажем, data-foo
). Элементы могут быть различными элементами тега.
<p data-foo="0"></p><br/><h6 data-foo="1"></h6>
Используя только JavaScript, каков наиболее эффективный способ выбрать все элементы DOM, которые имеют определенный data-
(скажем, data-foo
). Элементы могут быть различными элементами тега.
<p data-foo="0"></p><br/><h6 data-foo="1"></h6>
Вы можете использовать querySelectorAll:
document.querySelectorAll('[data-foo]');
document.querySelectorAll("[data-foo]")
предоставит вам все элементы с этим атрибутом.
document.querySelectorAll("[data-foo='1']")
будет получать только те, у которых значение равно 1.
<!DOCTYPE html>
<html>
<head></head>
<body>
<p data-foo="0"></p>
<h6 data-foo="1"></h6>
<script>
var a = document.querySelectorAll('[data-foo]');
for (var i in a) if (a.hasOwnProperty(i)) {
alert(a[i].getAttribute('data-foo'));
}
</script>
</body>
</html>
Пока он не такой симпатичный, как querySelectorAll
(который имеет множество проблем), здесь очень гибкая функция, которая рекурсирует DOM и должна работать в большинстве браузеров (старых и новых). Пока браузер поддерживает ваше условие (то есть: атрибуты данных), вы сможете получить элемент.
Любопытно: не утруждайте себя тестированием этого и QSA на jsPerf. Браузеры, такие как Opera 11, кэшируют запрос и искажают результаты.
код:
function recurseDOM(start, whitelist)
{
/*
* @start: Node - Specifies point of entry for recursion
* @whitelist: Object - Specifies permitted nodeTypes to collect
*/
var i = 0,
startIsNode = !!start && !!start.nodeType,
startHasChildNodes = !!start.childNodes && !!start.childNodes.length,
nodes, node, nodeHasChildNodes;
if(startIsNode && startHasChildNodes)
{
nodes = start.childNodes;
for(i;i<nodes.length;i++)
{
node = nodes[i];
nodeHasChildNodes = !!node.childNodes && !!node.childNodes.length;
if(!whitelist || whitelist[node.nodeType])
{
//condition here
if(!!node.dataset && !!node.dataset.foo)
{
//handle results here
}
if(nodeHasChildNodes)
{
recurseDOM(node, whitelist);
}
}
node = null;
nodeHasChildNodes = null;
}
}
}
Затем вы можете запустить его со следующим:
recurseDOM(document.body, {"1": 1});
для скорости или просто recurseDOM(document.body);
Пример с вашей спецификацией: http://jsbin.com/unajot/1/edit
Пример с различной спецификацией: http://jsbin.com/unajot/2/edit
var matches = new Array();
var allDom = document.getElementsByTagName("*");
for(var i =0; i < allDom.length; i++){
var d = allDom[i];
if(d["data-foo"] !== undefined) {
matches.push(d);
}
}
Не уверен, кто меня набросал с -1, но вот доказательство.
Он динамически создает правило стиля [...] Затем он просматривает весь документ (используя сильно осужденный и IE-специфический, но очень быстрый document.all) и получает вычисленный стиль для каждого из элементов. Затем мы ищем foo свойство на результирующем объекте и проверить, оценивается ли оно как "бар". Для каждого элемента, который соответствует, мы добавляем к массиву.