JQuery kullanmadan “data-” özelliğine sahip tüm öğeleri seçin


233

Yalnızca JavaScript kullanarak, belirli bir data-niteliğe sahip tüm DOM öğelerini seçmenin en etkili yolu nedir (diyelim data-foo). Öğeler farklı etiket öğeleri olabilir.

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

document.querySelectorAllIE7 üzerinde çalışmadığını unutmayın . DOM ağacında yürüyecek ve her etikette özniteliği kontrol edecek bir yedek komut dosyası oluşturmak zorunda kalacaksınız (aslında ne kadar hızlı querySelectorAllolduğu hakkında hiçbir fikrim yok ve etiketlerin manuel kontrolü için gidecekti).
tereško

JQuery kullanmamanızın nedeni nedir? Bu gibi durumlarda neredeyse yeri doldurulamaz ...
James Hay

@hayır bile bu öğeleri saf css bile seçebilirsiniz.
Knu

1
@JamesHay çünkü her çevre, şirket, site, kodlama standardı, neyiniz var, jQuery kullanımına izin veriyor. jQuery yeri doldurulamaz.
Carnix

1
Gerçekten üzerinde çalıştığı hala herhangi bir cevap görmüyorum farklı data- : elementler, yani data-foo=0ve data-bar=1 ve data-app="js" ve data-date="20181231"
Alex

Yanıtlar:



244
document.querySelectorAll("[data-foo]")

size bu özelliğe sahip tüm öğeleri getirir.

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

size yalnızca 1 değerine sahip olanları getirir.


Aldığınız öğelerin değerlerini nasıl ayarlayabilirsiniz?
Steven Aguilar

@StevenAguilar a .querySelectorAll()döndürür NodeList. Bu dokümanda belirtildiği gibi, kullanarak koleksiyonu tekrarlayabilirsiniz .forEach(). Bunun IE olmayan bir çözüm olduğunu unutmayın: developer.mozilla.org/en-US/docs/Web/API/… . IE'yi desteklemeniz gerekiyorsa, normal bir fordöngü kullanarak yalnızca NodeList üzerinde döngü yapmanız gerekir .
Joseph Marikle

13

Deneyin → burada

    <!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>

HasOwnProperty kullanmak 2016 yılında benim için en iyi cevap, bu Mdn hasOwnProperty
NVRM 29:06

QuerySelectorAll () öğesinden NodeList yinelenebilir (bir dizi olmasa da). İle döngü for in, uzunluk ve öğe özellikleri üzerinde yinelenecektir. Bunun yerine, for ofyinelenecek şekilde tasarlanmış özellikleri yinelemek için kullanın
Solvitieg

1

İşte ilginç bir çözüm: seçiciyle eşleşen öğelere kukla bir özellik eklemek için tarayıcı CSS motorunu kullanır ve ardından eşleşen öğeleri bulmak için hesaplanan stili değerlendirir:

Dinamik olarak bir stil kuralı oluşturur [...] Daha sonra tüm belgeyi tarar (çok decried ve IE'ye özgü ama çok hızlı document.all kullanarak) ve her bir öğe için hesaplanan stili alır. Daha sonra, sonuçta ortaya çıkan nesne üzerinde foo özelliğini ararız ve "bar" olarak değerlendirilip değerlendirilmediğini kontrol ederiz. Eşleşen her öğe için bir diziye ekleriz.


1
Evet, eski tarayıcılarla ilgili ipucunu kaldırdım.
Heinrich Ulbricht

Çok teşekkür ederim efendim;) İtiraf etmeliyim ki 5.
Heinrich Ulbricht

evet etiketi kaçırmak kolay. html5 olduğu için hepimiz document.querySelectorAll (ve data- * özniteliği de html5'e özgüdür) öneriyoruz.
shawndumas

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

Beni -1 ile kimin öldürdüğünden emin değilim, ama işte kanıt.

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


3
çoğunlukla "doğru" sadece doğru değil. Im emin birisi size -1 verdi çünkü öğeleri almak için ekstra iş bir sürü yapıyor, ve sonra bir dizi koleksiyonu koyarak. Bir açıklama yok zaman -1 sevmediğim vermedi.
Loktar

1
pahalıdır (sayfadaki tüm öğeler), dizi değişmez gösterimini de (yani []) kullanır ve bunun üstünde çalışmaz. kendiniz görün -> jsbin.com/ipisul/edit#javascript,html
shawndumas

2
OP yine de HTML 5 kullanıyor olsa da , eski IE derlemelerinde getElementsByTagNameglobal ( *) seçici bozuldu. Burada, özyinelemeli bir DOM araması işi yapar. Ayrıca, data-fooöznitelikten eşlenen bir ElementNode üzerinde "data-foo" özelliği yoktur . Aradığınız dataset: (nesnenin yani node.dataset.foo.

@shawndumas - sahip olduğunuz her şey bir PEBKAC idi. jsfiddle.net/D798K/2 . İşe yarıyor. Nihayetinde, bu cevap için kendimi -1 yapardım - OP'nin sorusundaki "en verimli" kelimelerini kaçırdım ...
Brian

@Brian - jsbin.com/ipisul one sizin için çalışıyor mu? çünkü jsfiddle biri benim (iş yeri talep) yani9 çalışmıyor ...
shawndumas

-4

Oldukça hoş olmasa da querySelectorAll(bir sorun litani vardır), DOM'u geri alan ve çoğu tarayıcıda (eski ve yeni) çalışması gereken çok esnek bir işlev. Tarayıcı durumunuzu desteklediği sürece (yani: veri özellikleri), öğeyi alabilmeniz gerekir.

Meraklı için: Bunu jsPerf'de QSA'ya karşı test etmekten çekinmeyin. Opera 11 gibi tarayıcılar sorguyu önbelleğe alır ve sonuçları eğriltir.

Kod:

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

Daha sonra aşağıdakilerle başlatabilirsiniz:

recurseDOM(document.body, {"1": 1}); hız için, ya da sadece recurseDOM(document.body);

Spesifikasyonunuza göre örnek: http://jsbin.com/unajot/1/edit

Farklı özelliklere sahip örnek: http://jsbin.com/unajot/2/edit


23
Sorunların yalancılığı nedir querySelectorAll?
ShreevatsaR

9
Ben de bu konuları duymak isterim.
Sean_A91

4
Şimdi, hangi litanın olduğunu asla bilemeyiz.
SO'dan

bunu küçümsüyorum. querySelectorAllApi
dman
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.