Sınıf adına göre alt öğe nasıl elde edilir?


131

Sınıfı 4 olan çocuk aralığını elde etmeye çalışıyorum. İşte örnek bir öğe:

<div id="test">
 <span class="one"></span>
 <span class="two"></span>
 <span class="three"></span>
 <span class="four"></span>
</div>

Elimdeki araçlar JS ve YUI2'dir. Bunun gibi bir şey yapabilirim:

doc = document.getElementById('test');
notes = doc.getElementsByClassName('four');

//or

doc = YAHOO.util.Dom.get('#test');
notes = doc.getElementsByClassName('four');

Bunlar IE'de çalışmaz. Nesnenin (doc) bu yöntemi veya özelliği (getElementsByClassName) desteklemediğine dair bir hata alıyorum. GetElementsByClassName'in tarayıcılar arası uygulamalarının birkaç örneğini denedim, ancak onları çalıştıramadım ve hala bu hatayı alıyorum.

Sanırım ihtiyacım olan şey tarayıcılar arası getElementsByClassName veya doc.getElementsByTagName ('span') kullanmam ve 4. sınıfı bulana kadar döngü yapmam gerekiyor. Yine de bunu nasıl yapacağımdan emin değilim.



1
Yeterince komik, daha güçlü querySelectorAllolanı IE 8+ getElementsByClassNametarafından desteklenirken yalnızca IE 9+ tarafından destekleniyor. IE 7'yi düşürebilirseniz, güvenle kullanabilirsiniz querySelectorAll('.4'). Bu arada, 4geçersiz bir sınıf adı.
Prinzhorn

@paritybit bu soru hala getElementsByClassName kullandığı için çalışmıyor ve IE'nin eski sürümü bunu desteklemiyor gibi görünüyor. edit: Üzgünüm etiket adı kullanıyor. Bu işe yarayabilir.
spyderman4g63

@Prinzhorn Bazı nedenlerden dolayı bu üründe YUI2 seçici yardımcı programım yok.
spyderman4g63

@ spyderman4g63 YUI2'ye özgü hiçbir şeyden bahsetmedim. document.querySelectorAllDOM ve YUI ile ilgisi yok
Prinzhorn

Yanıtlar:


85

doc.childNodesHer birini yinelemek spanve ardından classNameeşit olanı filtrelemek için kullanın 4:

var doc = document.getElementById("test");
var notes = null;
for (var i = 0; i < doc.childNodes.length; i++) {
    if (doc.childNodes[i].className == "4") {
      notes = doc.childNodes[i];
      break;
    }        
}


1
Sorun getElementsByClassName'in IE8'de çalışmamasıdır.
spyderman4g63

7
Elemanın birden fazla sınıfı varsa bu kod çalışmaz. Örneğin: "bir" sınıfı olan öğeleri arıyorsanız ve öğelerinizin "bir iki üç" sınıfı varsa, bu işlev onları bulamayacaktır.
Fran Verona

3
@FranVerona Merak ettiğim için, basit bir "indexOf ('className')> -1" çoklu sınıf sorununu çözmez mi?
James Poulose

2
@JamesPoulose, olmaz . İki sınıfa ayarlanmış bir öğeye sahip olmayı düşünün: küçük ve büyük. thatElement.className, "küçük daha büyük" e eşit olan bir Dize döndürür. Eğer büyük deyimiyle myElement.className.indexOf ("büyük") adlı bir sınıf arıyorsanız, aslında sınıfın bir parçası olmamasına rağmen negatif 1'e eşit olmayan bir şey üretecektir. Sınıf adlarınız üzerinde% 100 kontrolünüz varsa, böyle bir düzeltme işe yarayacaktır, özellikle de üzerinde tam kontrole sahip olmadığınız kodla etkileşime girecek bir kod yazarken garanti edilmez.
deadboy

classNameBenzer şekilde bir normal ifade eşleşmesi kullanmalısınız : if(doc.childNode[i].className.match("\s*" + search_class + "\s*")burada değişken search_class, aradığınız sınıf adıdır.
WebWanderer

130

QuerySelector ve querySelectorAll kullanma

var testContainer = document.querySelector('#test');
var fourChildNode = testContainer.querySelector('.four');

IE9 ve üstü

;)


Akıllı çözümünüz için teşekkürler!
Tai Jinyuan'ı

1
Bu sadece çocukları değil tüm torunları kontrol eder.
SUM1

47

Kabul edilen cevap yalnızca acil çocukları kontrol eder. Çoğu zaman bu sınıf adına sahip herhangi bir torun arıyoruz.

Ayrıca, bazen bir className içeren herhangi bir çocuğu isteriz .

Örneğin: tam<div class="img square"></div> olarak className "img" olmasa da, className "img" üzerindeki bir aramayla eşleşmelidir .

İşte bu sorunların her ikisi için bir çözüm:

Sınıfla birlikte bir alt öğenin ilk örneğini bulun className

   function findFirstChildByClass(element, className) {
        var foundElement = null, found;
        function recurse(element, className, found) {
            for (var i = 0; i < element.childNodes.length && !found; i++) {
                var el = element.childNodes[i];
                var classes = el.className != undefined? el.className.split(" ") : [];
                for (var j = 0, jl = classes.length; j < jl; j++) {
                    if (classes[j] == className) {
                        found = true;
                        foundElement = element.childNodes[i];
                        break;
                    }
                }
                if(found)
                    break;
                recurse(element.childNodes[i], className, found);
            }
        }
        recurse(element, className, false);
        return foundElement;
    }

7
Hayır! Ben yok Tüm alt istiyorum soru gibi sadece çocuk istedi.
Paul Draper

14
Whelp. Yorumunuz gerekliydi. (Benim gibi) benzer ama belki de daha karmaşık veya genel problemlerini çözmek için benzer cevaplar arayan 13 kişiye yardım ettiğime sevindim.
Augie Gardner

5
tnx, bu cevabın daha fazla kullanım durumuna uygun olduğunu düşünüyorum
Boban Stojanovski

Kayıt için, her iki kullanım durumum da oldu, torunları biraz daha sık, ama buraya çocuk kullanım durumu için geldim.
SUM1

14

Element.querySelector () kullanın. Farz edelim: 'myElement' zaten sahip olduğunuz ana öğe. 'sonClassName', aradığınız çocuğun sınıfıdır.

let child = myElement.querySelector('.sonClassName');

Daha fazla bilgi için şu adresi ziyaret edin: https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelector


Nedense let child = myElement.querySelector('sonClassName');benim durumumda kullanmak zorunda kaldım
malat

Ancak sınıf adı querySelector'ın ('. SonClassName') yanına noktayı eklemelisiniz, aksi takdirde sonClassName bir sınıf adı değil etiket adı olduğu için işleyecektir
Hamza Dahmoun

10

Deneyebilirsin:

notes = doc.querySelectorAll('.4');

veya

notes = doc.getElementsByTagName('*');
for (var i = 0; i < notes.length; i++) { 
    if (notes[i].getAttribute('class') == '4') {
    }
}

1
Tarayıcıların nihayet jQuery gibi bir şeye ihtiyaç duymadan bu işlevselliğe sahip olup olmadığını merak ediyordum, bunu gördüğüme sevindim. Meraklı biri varsa, çoğu modern tarayıcıda destekleniyor gibi görünüyor: developer.mozilla.org/en-US/docs/Web/API/Document/…
Liron Yahdav

8

Bana göre dördüncü açıklığı istiyorsun. Öyleyse, şunu yapabilirsiniz:

document.getElementById("test").childNodes[3]

veya

document.getElementById("test").getElementsByTagName("span")[3]

Bu sonuncusu, onu bozabilecek herhangi bir gizli düğüm olmamasını sağlar.


1
Teşekkürler, ancak değişken miktarda alt öğe var.
spyderman4g63

1
Bana göre soru her zaman dördüncü açıklık çocuğunu elde etmekti, böylece cevabıma yol açtı. Elbette, başka bir öğe içindeki herhangi bir indekste herhangi bir öğe türünü elde etmek için bir işlevin daha iyi olacağına katılıyorum, ancak soruyu böyle yorumlamadım ... soruyu tekrar okuduktan sonra tamamen yanlış anladığımı görüyorum: - )
Christian Jørgensen

TagNamebu kadar! Çok basit.
Jacksonkr

İlk öğeyi almak için bu tekniği sık sık kullanıyorum, örneğin document.getElementById ("test"). ChildNodes [0]
Louise Eggleton

@LouiseEggleton var .firstChildve .firstChildElementgerçi
YakovL

4

Ancak eski tarayıcıların desteklemediğini unutmayın getElementsByClassName.

O zaman yapabilirsin

function getElementsByClassName(c,el){
    if(typeof el=='string'){el=document.getElementById(el);}
    if(!el){el=document;}
    if(el.getElementsByClassName){return el.getElementsByClassName(c);}
    var arr=[],
        allEls=el.getElementsByTagName('*');
    for(var i=0;i<allEls.length;i++){
        if(allEls[i].className.split(' ').indexOf(c)>-1){arr.push(allEls[i])}
    }
    return arr;
}
getElementsByClassName('4','test')[0];

Görünüşe göre işe yarıyor, ancak bir HTML sınıfının

  • Bir harfle başlamalıdır: AZ veya az
  • Ardından harfler (A-Za-z), rakamlar (0-9), kısa çizgiler ("-") ve alt çizgiler ("_") gelebilir

3

Kimliğin adını, önünde işaret getElementByIdyok ile kullanın #. Ardından spanalt düğümleri getElementsByTagNamekullanabilir ve doğru sınıfa sahip olanı bulmak için bunlardan geçebilirsiniz:

var doc = document.getElementById('test');

var c = doc.getElementsByTagName('span');

var e = null;
for (var i = 0; i < c.length; i++) {
    if (c[i].className == '4') {
        e = c[i];
        break;
    }
}

if (e != null) {
    alert(e.innerHTML);
}

Demo: http://jsfiddle.net/Guffa/xB62U/


Maalesef bu # bir yazım hatasıydı. Kapsayıcı div'i seçebilirim, ancak alt öğeleri etiket adına göre seçemiyorum çünkü bu işlev ie8'de çalışmıyor.
spyderman4g63

@ spyderman4g63: getElementsByTagNameYöntem IE 8'de çalışır. IE 5.5'e kadar desteklenmektedir.developer.mozilla.org/en-US/docs/DOM/…
Guffa

3

Bana göre, yapabildiğiniz her seferinde Array ve yöntemlerini kullanmalısınız. Tüm DOM / sarmalayıcı üzerinden döngüden veya boş diziye bir şeyler göndermekten çok, çok daha hızlıdırlar. Burada sunulan çözümlerin çoğuna burada açıklandığı gibi Naive diyebilirsiniz (harika makale btw):

https://medium.com/@chuckdries/traversing-the-dom-with-filter-map-and-arrow-functions-1417d326d2bc

Çözümüm : (Codepen canlı önizleme: https://codepen.io/Nikolaus91/pen/wEGEYe )

const wrapper = document.getElementById('test') // take a wrapper by ID -> fastest
const itemsArray = Array.from(wrapper.children) // make Array from his children

const pickOne = itemsArray.map(item => { // loop over his children using .map() --> see MDN for more
   if(item.classList.contains('four')) // we place a test where we determine our choice
     item.classList.add('the-chosen-one') // your code here
})

1

Bunu jquery kullanarak yapmamın yolu şöyle bir şey ..

var targetchild = $ ("# test"). children (). find ("span.four");


14
soru javascript ile ilgili değil jQuery
Jya

1

İşte nispeten basit bir özyinelemeli çözüm. Bence burada kapsamlı bir arama uygun. Bu, bulunan sınıfla eşleşen ilk öğeyi döndürür.

function getDescendantWithClass(element, clName) {
    var children = element.childNodes;
    for (var i = 0; i < children.length; i++) {
        if (children[i].className &&
            children[i].className.split(' ').indexOf(clName) >= 0) {
            return children[i];
         }
     }
     for (var i = 0; i < children.length; i++) {
         var match = getDescendantWithClass(children[i], clName);
         if (match !== null) {
             return match;
         }
     }
     return null;
}

1

Aşağıdaki satırı ekleyerek üst sınıfı getirebilirsiniz. Bir kimliğin olsaydı, daha kolay olurdu getElementById. Her şeye rağmen,

var parentNode = document.getElementsByClassName("progress__container")[0];

Ardından , sınıfla eşleşen tüm e-postaları getirmek querySelectorAlliçin üst <div>öğe üzerinde kullanabilirsiniz .div.progress__marker

var progressNodes = progressContainer.querySelectorAll('.progress__marker');

querySelectorAlldivsınıfıyla her şeyi getirecekprogress__marker


1

Modern çözüm

const context = document.getElementById('context');
const selected = context.querySelectorAll(':scope > div');

belgeleme


0

Haziran 2018 ES6 güncelleştirmesi

    const doc = document.getElementById('test');
    let notes = null;
    for (const value of doc) {
        if (value.className === '4') {
            notes = value;
            break;
        }    
    }

-2

Hmm. Örnek IE8'de çalışıyor, ancak bir nesneye uyguladığınızda işe yaramayabilir. Benim durumumda, doc bir yui dom nesnesi olarak ayarlanır ve ardından doc.getElementsByClassName kullanılır. İşte o zaman başarısız olur. düzenleme: veya belki bu nesnenin nasıl çalıştığını anlamıyorum ve bu sadece normal bir dom nesnesi mi?
spyderman4g63

@ spyderman4g63 YUI sürümünün getElementsByClassNamebir yöntemidir YAHOO.util.Dom. Sizin durumunuzda, arama şuna benzer YAHOO.util.Dom.getElementsByClassName('four', 'span', 'test'). Bu aramanın ne yaptığını daha ayrıntılı bir şekilde anlamak için muhtemelen belgeleri okumalısınız. Kısa versiyon artık arayacaktır olmasıdır spansınıfla elemanları fourile DOM öğesinin altında testolarak onun id.
Hank Gay

@ spyderman4g63 Evet, getçağrının sonucu sadece bir DOM öğesidir. YUI, jQuery gibi bir şeyin yaptığı gibi tam satış 'her şeyi çerçeveye özgü bir nesneye sarma' yaklaşımını benimsemez ve Prototype gibi yerel nesnelere maymun yamalı yapmaz (yapmadı mı? sonsuza kadar). Bu bakımdan YUI daha çok Dojo'ya benziyor.
Hank Gay

-3

YUI seçicilerini kullanarak bunu nasıl yaptım. Hank Gay'in önerisi sayesinde.

notes = YAHOO.util.Dom.getElementsByClassName('four','span','test');

burada dört = sınıf adı, span = öğe türü / etiket adı ve test = üst kimlik.


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.