2012-04-17 23 views
19

İç içe geçmiş çocuk listeleri içeren bir listeniz olduğunu varsayalım.DOM koleksiyonundaki `querySelectorAll 'özelliğini kullanan çocuk seçici

<ul> 
    <li></li> 
    <li> 
     <ul> 
      <li></li> 
      <li></li> 
     </ul> 
    </li> 
    <li></li> 
</ul> 

Ve bir seçim yapmak için document.querySelectorAll() kullanın:

var ul = document.querySelectorAll("ul"); 
i doğrudan alt öğeleri almak için ul koleksiyonu nasıl kullanabilirim

?

ul.querySelectorAll("> li"); 
// Gives 'Error: An invalid or illegal string was specified' 

en ul şekilde önbelleğe alınır (Aksi ı doğrudan ul > li yapmış olabilir) tahmin edelim.

$("ul").find("> li"); 

Ama yerli querySelectorAll değil yapar:

jQuery bu çalışır. Herhangi bir çözüm?

+2

seçici gerçekten mantıklı değil o. JQuery ile '.find ("> li ")' yerine '.children (" li ")' yi kullanırsınız. Aslında hiç şaşırmadım. –

+0

@ MДΓΓБДLL '.find ('> li ul span')' OP'nin örneğinde olduğu gibi kendi başına çok da faydalı değildir. – alex

+0

@ MДΓΓБДLL örnek biraz çekişmeli, ama kesinlikle bir gerçek dünya kullanım durumu vardır :) – Husky

cevap

12

ul döndürülmüş bir NodeList olduğundan, dolaylı olarak jQuery koleksiyonu gibi içeriğini üzerinde döngü yapmaz. ul[0].querySelectorAll()'u kullanmanız veya daha iyisi'u querySelector() ile seçmeniz gerekir. Ayrıca, querySelectorAll(), , > almaz ve geçerli bağlamından çalışır. Ancak, (gerçi tarayıcı uyumluluğu kontrol) o lazd's answer kullanarak işe alabilirsiniz ya da (hayır tarayıcılarda sorun olmalı) bu geçici çözümlerden herhangi ...

[].filter.call(ul.querySelectorAll("li"), function(element){ 
    return element.parentNode == ul; 
}); 

jsFiddle.

Bu, ul soyundan gelen tüm li öğelerini seçer ve daha sonra doğrudan torun olmayanları kaldırır.

Alternatif olarak, ... filtrelemedikçe sonra

[].filter.call(ul.childNodes, function(node) { 
    return node.nodeType == 1 && node.tagName.toLowerCase() == 'li'; 
}); 

jsFiddle tüm childNodes almak ve olabilir.

+0

Yup, uygulanabilir bir çözüm gibi görünüyor.Çok kötü, tek bir karakterde ne yapılabildiğini üç satırlık kod alır :) 'filter '' işlevi,' ul' bir NodeList olduğundan çalışmamasına dikkat edin, bu yüzden 'Array.prototype.slice yapmalısınız. ilk önce. – Husky

+0

@Husky Ben de yazdığım şekilde çalışacak. – alex

+0

@Husky Bunu bir fonksiyon olarak her zaman 'Element.prototype' öğesine ekleyebilirsiniz :) –

0

document.querySelectorAll() tarafından döndürülen NodeList üzerinden yinelemeniz gerekir ve bu listedeki her öğe için element.querySelectorAll()'u arayın.

36

Geçerli öğeye "köklenen" bir seçici yazmak için doğru yol :scope kullanmaktır.

ul.querySelectorAll(":scope > li"); 

bir açıklama ve sağlam, çapraz tarayıcı çözüm için buraya cevabımı bakınız: https://stackoverflow.com/a/21126966/1170723

+2

Bunu görmek güzel! :) – alex

+5

[Tarayıcı uyumluluğu] 'nı aklınızda bulundurun (https://developer.mozilla.org/en-US/docs/Web/CSS/%3ascope#Browser_compatibility): Chrome: evet, FF: 32, IE: no, opera: no, Safari: 7 @ –

+0

, @Web_Designer'ın söylediklerine ek olarak, bugüne kadar * hala * Microsoft Edge'de desteklenmiyor. QuerySelectorAll 'kapsamı' kullanmaya çalışıyorum bir sözdizimi hatası verir. "JQuery'ye ihtiyacınız yok" kampı için çok fazla. – TKoL

İlgili konular