Kitaplıkları kullanmadan querySelectorAll kullanılamadığında öğeler özniteliğe göre alınsın mı?


123
<p data-foo="bar">

Bunun eşdeğerini nasıl yapabilirsiniz?

document.querySelectorAll('[data-foo]')

nerede querySelectorAll olan mevcut değil ?

En azından IE7'de çalışan yerel bir çözüme ihtiyacım var. IE6 umrumda değil.


kontrol sizzle.js JavaScript seçici kütüphanesi
devrin

1
Güzel evet, yapmam gereken tek seçim veri öznitelikleridir, bu yüzden Sizzle gibi bütün bir seçici motoru çekmeden bunu yamamanın en basit yolunu bulmaya çalışıyordum. Ancak kaynağa bakmak iyi bir nokta. BTW bir başka harika seçici motor github.com/ded/qwery
ryanve

@ryanve, teşekkürler bir göz atacağım :)
epoch

Kullandığım çalışma çözümü github.com/ryanve/dope/blob/master/dope.js içinde 'queryAttr' adlı yöntemde
ryanve

7
Lol, sorunuz benim cevabım. Yani bu başka bir soruyla geliyor. Hangi durumda querySelectorAllmevcut değil? note - I don't care all IE
vzhen

Yanıtlar:


136

GetElementsByTagName ('*') çalıştıran ve yalnızca "data-foo" özelliğine sahip öğeleri döndüren bir işlev yazabilirsiniz:

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

Sonra,

getAllElementsWithAttribute('data-foo');

8
Kullanımı != nullen ideal yolu olduğunu (daha iyi benim yukarıdaki yorumun yerine) getAttribute olan bir değer döndürmek için eski IE'de mümkün olduğu için typeofise'number'
ryanve

1
Neden document.getElementsByTagName('*')yerine kullanıyorsunuz document.all?
pedrozath

1
Değerini değil, yalnızca varoluşu kontrol etmek istediğiniz için neden hasAttributeyerine kullanmayasınız getAttribute() !== null?
rvighne

61

kullanım

//find first element with "someAttr" attribute
document.querySelector('[someAttr]')

veya

//find all elements with "someAttr" attribute
document.querySelectorAll('[someAttr]') 

özniteliklerine göre öğeleri bulmak için. Artık tüm ilgili tarayıcılarda (hatta IE8) destekleniyor: http://caniuse.com/#search=queryselector


2
Soru açıkça şunu talep ettiğinde, bunun nasıl bu kadar çok olumlu oyu var: " En azından IE7'de çalışan yerel bir çözüme ihtiyacım var ". İkincisi, bu bağlantı, desteğin aslında IE8'den başlamasına rağmen IE11'de başladığını belirtir - belki de bu, developer.mozilla.org/en-US/docs/Web/API/Element/… ile değiştirilmelidir, böylece aslında yanıtı destekler. ..?
Zze

7
Tüm olumlu oyların nedeni ve cevabı vermemin nedeni, bu SO sorusunun gerçekten eski olması, bu nedenle DOM öğelerini nasıl bulacağınızı ararken bu soruyu arama sonuçlarında çok yüksek buluyorsunuz ve insanlar ek oy arıyorlar. Kullanışlılık> tarihsel doğruluk. İkincisi, bağlantı hala gayet iyi çalışıyor, sadece caniuse.com'da gizli eski tarayıcılar var, "Kullanım göreli" seçeneğine geçerseniz eski tarayıcıları görmeye devam edeceksiniz.
Pylinux

Mükemmel çalıştı. Hızlı ve basit
Dawson B

Yıl 2020. Şimdi kabul edilen cevap bu olmalı.
NearHuscarl

44

Biraz oynadım ve bu ham çözüme ulaştım:

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

Kullanımı oldukça basittir ve IE8'de bile çalışır:

getElementsByAttribute('data-foo');
// or with parentNode
getElementsByAttribute('data-foo', document);

http://fiddle.jshell.net/9xaxf6jr/

Ancak bunun için / kullanmanızı tavsiye ederim (ve eski tarayıcıları desteklemek için bir polyfill kullanın ):querySelectorAll

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

Evet, querySelectorAll için +1. Hızlı bir jsperf testi jsperf.com/custom-vs-selectorall-attributes , kabul edilen cevaptan çok daha hızlı olduğunu gösteriyor ... maalesef IE 7 uyumlu değil :(
Sebastien Daniel

11

Bunu deneyin işe yarıyor

document.querySelector ([öznitelik = "değeri,"] ')

misal :

document.querySelector('[role="button"]')

5

Bu da işe yarıyor:

document.querySelector([attribute="value"]);

Yani:

document.querySelector([data-foo="bar"]);

2
Bu, gerçek querySelector'daki tek tırnak işaretleri eksik. Olmalı: document.querySelector('[data-foo="bar"]');
Brettins

1

Bunu deneyin - yukarıdaki cevapları biraz değiştirdim:

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

Sonra,

getAttributes('data-foo');

3
Neyi değiştirdin ve neden?
Artjom B.

1

@Kevinfahy'nin cevabında , gerekirse özniteliği değere göre almaya izin vermek için küçük bir değişiklik :

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

Tarayıcıda kullanmayın

Tarayıcıda kullanın document.querySelect('[attribute-name]').

Ancak birim testi yapıyorsanız ve alay edilen dom'unuzda flakey querySelector uygulaması varsa, bu işinizi görecektir.

Bu @ kevinfahy'nin cevabı, ES6 şişman ok işlevleriyle ve belki de okunabilirlik pahasına HtmlCollection'ı bir diziye dönüştürerek biraz kısaltıldı.

Yani sadece bir ES6 aktarıcısı ile çalışacaktır. Ayrıca, birçok öğeyle ne kadar performanslı olacağından emin değilim.

function getElementsWithAttribute(attribute) {
  return [].slice.call(document.getElementsByTagName('*'))
    .filter(elem => elem.getAttribute(attribute) !== null);
}

Ve işte belirli bir değere sahip bir özellik alacak bir varyant

function getElementsWithAttributeValue(attribute, value) {
  return [].slice.call(document.getElementsByTagName('*'))
    .filter(elem => elem.getAttribute(attribute) === value);
}
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.