Выделите все элементы с атрибутом «data-», не используя jQuery - PullRequest
158 голосов
/ 17 августа 2011

Используя только JavaScript, какой самый эффективный способ выбрать все элементы DOM, которые имеют определенный атрибут data- (скажем, data-foo).Элементы могут быть различными элементами тега.

<p data-foo="0"></p><br/><h6 data-foo="1"></h6>

Ответы [ 6 ]

302 голосов
/ 17 августа 2011

Вы можете использовать querySelectorAll :

document.querySelectorAll('[data-foo]');
173 голосов
/ 17 августа 2011
document.querySelectorAll("[data-foo]")

даст вам все элементы с этим атрибутом.

document.querySelectorAll("[data-foo='1']")

получит только элементы со значением 1.

11 голосов
/ 17 августа 2011

Попробуйте → здесь

    <!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>
0 голосов
/ 17 августа 2011

Хотя это и не так красиво, как 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

0 голосов
/ 17 августа 2011

Здесь представляет собой интересное решение: он использует движок CSS браузеров для добавления фиктивного свойства к элементам, соответствующим селектору, а затем оценивает вычисленный стиль для поиска соответствующих элементов:

Он динамически создает правило стиля [...]. Затем он сканирует весь документ (используя очень упорядоченный и специфичный для IE, но очень быстрый document.all) и получает вычисленный стиль для каждого из элементов.Затем мы ищем свойство foo в результирующем объекте и проверяем, оценивается ли оно как «bar».Для каждого соответствующего элемента мы добавляем в массив.

0 голосов
/ 17 августа 2011
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, но вот доказательство.

http://jsfiddle.net/D798K/2/

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