web-dev-qa-db-fra.com

Sélectionnez tous les éléments avec l'attribut "data-" sans utiliser jQuery

En utilisant uniquement JavaScript, quel est le moyen le plus efficace de sélectionner tous les éléments DOM ayant un certain attribut data- (disons data-foo). Les éléments peuvent être différents éléments de balises.

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

Vous pouvez utiliser querySelectorAll :

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

vous obtiendrez tous les éléments avec cet attribut.

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

vous obtiendrez seulement ceux avec une valeur de 1.

186
Joseph Marikle

Essayez-le → ici

    <!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>
11
shawndumas
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);
    }
}

Je ne sais pas qui m'a piqué avec -1, mais voici la preuve.

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

0
Brian

Here est une solution intéressante: il utilise le moteur CSS des navigateurs pour ajouter une propriété fictive aux éléments correspondant au sélecteur, puis évalue le style calculé pour rechercher les éléments correspondants:

Il crée dynamiquement une règle de style [...] Il analyse ensuite le document entier (en utilisant le document.all très décrié et spécifique à IE mais très rapide) et obtient le style calculé pour chacun des éléments. Nous recherchons ensuite la propriété foo sur l'objet résultant et vérifions si elle est évaluée comme "barre". Pour chaque élément qui correspond, nous ajoutons à un tableau.

0
Heinrich Ulbricht

Bien que pas aussi joli que querySelectorAll (qui a une litanie de problèmes), voici une fonction très flexible qui recourt au DOM et devrait fonctionner dans la plupart des navigateurs (anciens et nouveaux). Tant que le navigateur prend en charge votre condition (c'est-à-dire: attributs de données), vous devriez pouvoir récupérer l'élément.

Pour les curieux: Ne vous fatiguez pas à tester ceci contre QSA sur jsPerf. Des navigateurs comme Opera 11 mettront la requête en cache et inclineront les résultats.

Code:

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;
        }
    }
}

Vous pouvez ensuite l'initialiser avec les éléments suivants:

recurseDOM(document.body, {"1": 1}); pour la vitesse, ou simplement recurseDOM(document.body);

Exemple avec votre spécification: http://jsbin.com/unajot/1/edit

Exemple avec spécification différente: http://jsbin.com/unajot/2/edit

0
user1385191