클래스 이름으로 자식 요소를 얻는 방법?


131

클래스 = 4 인 자식 범위를 얻으려고합니다. 예제 요소는 다음과 같습니다.

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

내가 사용할 수있는 도구는 JS와 YUI2입니다. 나는 이런 식으로 할 수 있습니다 :

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

//or

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

IE에서는 작동하지 않습니다. 객체 (doc) 가이 메소드 또는 속성 (getElementsByClassName)을 지원하지 않는다는 오류가 발생합니다. getElementsByClassName의 크로스 브라우저 구현에 대한 몇 가지 예를 시도했지만 작동시키지 못했지만 여전히 오류가 발생했습니다.

크로스 브라우저 getElementsByClassName이 필요하다고 생각하거나 doc.getElementsByTagName ( 'span')을 사용하고 클래스 4를 찾을 때까지 반복해야합니다. 그래도 어떻게 해야할지 모르겠습니다.



1
querySelectorAll재미있게도 IE 8 이상에서는 더 강력 getElementsByClassName하고 IE 9 이상에서만 지원됩니다. IE 7을 버릴 수 있다면 안전하게 사용할 수 있습니다 querySelectorAll('.4'). 그건 그렇고, 4유효하지 않은 클래스 이름입니다.
Prinzhorn

@paritybit 그 질문은 여전히 ​​getElementsByClassName을 사용하고 이전 버전의 IE는 그것을 지원하지 않기 때문에 작동하지 않습니다. 편집 : 태그 이름을 사용하여 죄송합니다. 작동 할 수 있습니다.
spyderman4g63

@Prinzhorn이 제품에서 어떤 이유로 YUI2 선택기 유틸리티를 사용할 수 없습니다.
spyderman4g63

@ spyderman4g63 나는 YUI2에 대해 아무것도 이야기하지 않았다. document.querySelectorAllDOM이며 YUI와 관련이 없습니다
Prinzhorn

답변:


85

사용하여 doc.childNodes각각의 반복에 span, 그리고 그 하나의 필터 className같음 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
문제는 getElementsByClassName이 IE8에서 작동하지 않는다는 것입니다.
spyderman4g63

7
element에 둘 이상의 클래스가있는 경우이 코드가 작동하지 않습니다. 예를 들어, "1"클래스의 요소를 찾고 있고 요소에 "1 2 3"클래스가있는 경우이 함수는 해당 요소를 찾지 않습니다.
Fran Verona

3
@FranVerona 호기심 때문에 단순한 "indexOf ( 'className')> -1"이 여러 클래스 문제를 해결하지 않습니까?
James Poulose

2
@JamesPoulose 는 그렇지 않습니다 . 요소를 작고 큰 두 클래스로 설정하는 것을 고려하십시오. thatElement.className은 "작은 더 큰"문자열을 반환합니다. big이라는 클래스를 찾고 있다면 myElement.className.indexOf ( "big")는 실제로 클래스의 일부가 아니지만 음수 1과 다른 것을 생성합니다. 클래스 이름을 100 % 제어 할 수 있다면 그러한 수정이 효과가있을 것입니다. 특히 코드와 상호 작용하는 코드를 작성할 때 완전히 제어 할 수는 없습니다.
deadboy

다음 className과 같이 정규식 일치를 사용해야합니다 . if(doc.childNode[i].className.match("\s*" + search_class + "\s*")여기서 변수 search_class는 찾고자하는 클래스 이름입니다.
WebWanderer

130

querySelector 및 querySelectorAll 사용

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

IE9 이상

;)


스마트 솔루션에 감사드립니다!
Tai JinYuan

1
이것은 어린이뿐만 아니라 모든 자손을 검사합니다.
SUM1

47

허용 된 답변은 직계 어린이 만 확인합니다. 종종 우리는 그 클래스 이름을 가진 자손을 찾고 있습니다.

또한 때로는 className 을 포함 하는 자식을 원할 수도 있습니다 .

예를 들어 : <div class="img square"></div>그것은, 비록 클래스 명 "IMG"에 대한 검색과 일치해야 정확한 클래스 이름은 "IMG"가되지 않습니다.

이 두 가지 문제에 대한 해결책은 다음과 같습니다.

클래스가있는 자손 요소의 첫 번째 인스턴스를 찾습니다. 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
아니. 나는 모든 자손을 원하지 않습니다 . 질문과 같은 아이 만 있습니다.
Paul Draper

14
강아지. 귀하의 의견이 필요했습니다. 다행스럽게도 저와 같은 13 명의 다른 사람들이 비슷한 대답을 검색하여 유사하지만 아마도 더 복잡하거나 일반적인 문제를 해결하도록 도와주었습니다.
Augie Gardner

5
TNX, 난이 응답 한 벌 더 사용 사례를 생각
Boban Stojanovski에게

기록을 위해, 나는 두 가지 유스 케이스와 후손을 약간 더 자주 보았지만 어린이 유스 케이스를 위해 여기에 왔습니다.
SUM1

14

element.querySelector ()를 사용하십시오. 'myElement'는 이미 가지고있는 상위 요소입니다. 'sonClassName'은 찾고있는 자녀의 클래스입니다.

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

자세한 내용을 보려면 다음 사이트를 방문하십시오 : https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelector


어떤 이유로 나는 let child = myElement.querySelector('sonClassName');나의 경우 에 사용해야 했다
malat

그러나 클래스 이름 querySelector ( '. sonClassName') 옆에 점을 추가해야합니다. 그렇지 않으면 sonClassName이 클래스 이름이 아닌 태그 이름이기 때문에 처리합니다.
Hamza Dahmoun

10

시도해 볼 수 있습니다 :

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

또는

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

1
브라우저가 jQuery와 같은 것을 요구하지 않고 마침내이 기능을 가지고 있는지 궁금합니다. 궁금한 사람이 있다면 대부분의 최신 브라우저에서 지원되는 것 같습니다 : developer.mozilla.org/en-US/docs/Web/API/Document/…
Liron Yahdav

8

나에게 네 번째 범위를 원하는 것 같습니다. 그렇다면 다음을 수행하십시오.

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

또는

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

이 마지막 방법은 엉망이 될 수있는 숨겨진 노드가 없는지 확인합니다.


1
고맙지 만 다양한 양의 자식 요소가 있습니다.
spyderman4g63

1
나에게 그것은 문제가 항상 네 번째 스팬 아이를 얻는 것 같았 기 때문에 내 대답으로 이어졌습니다. 물론 다른 요소의 색인에있는 모든 유형의 요소를 얻는 함수가 더 좋을 것이라는 데 동의하지만, 그런 질문을 해석하지 않았습니다 ... 다시 질문을 읽으면 완전히 오해 된 것을 알 수 있습니다. )
Christian Jørgensen

TagName그게 다야! 너무 간단합니다.
Jacksonkr

나는 첫 번째 요소 예를 들어 document.getElementById를 ( "테스트")를 얻기 위해 자주이 기술을 사용 childNodes에 [0].
루이스 Eggleton

@LouiseEggleton있다 .firstChild.firstChildElement생각
YakovL

4

그러나 이전 브라우저는을 지원하지 않습니다 getElementsByClassName.

그런 다음 할 수 있습니다

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

작동하는 것 같지만 HTML 클래스는

  • AZ 또는 az로 시작해야합니다.
  • 뒤에 문자 (A-Za-z), 숫자 (0-9), 하이픈 ( "-") 및 밑줄 ( "_")이 올 수 있습니다.

3

앞에 ID를 부호 getElementById없이 사용 #하십시오. 그런 다음을 span사용하여 자식 노드를 가져 와서 getElementsByTagName루프하여 올바른 클래스가있는 노드 를 찾을 수 있습니다.

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

데모 : http://jsfiddle.net/Guffa/xB62U/


죄송합니다. #은 오타였습니다. 컨테이너 div를 선택할 수 있지만 해당 기능이 ie8에서 작동하지 않기 때문에 태그 이름으로 하위 요소를 선택할 수 없습니다.
spyderman4g63

@ spyderman4g63 :이 getElementsByTagName방법은 IE 8에서 작동합니다. IE 5.5까지 지원됩니다. developer.mozilla.org/en-US/docs/DOM/…
Guffa

3

제 생각에는 가능할 때마다 Array와 그 방법을 사용해야합니다. 그것들은 전체 DOM / 래퍼를 반복하거나 빈 배열로 물건을 밀어 넣는 것보다 훨씬 빠릅니다. 여기에 제시된 대부분의 솔루션은 여기에 설명 된대로 Naive에 전화 할 수 있습니다 (큰 기사 btw).

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

내 솔루션 : (Codepen의 실시간 미리보기 : 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

jquery를 사용 하여이 작업을 수행하는 방법은 다음과 같습니다.

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


14
질문은 jQuery가 아닌 자바 스크립트에 관한 것입니다.
Jya

1

다음은 비교적 간단한 재귀 솔루션입니다. 너비 우선 검색이 여기에 적합하다고 생각합니다. 찾은 클래스와 일치하는 첫 번째 요소를 반환합니다.

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

아래 줄을 추가하여 부모 클래스를 가져올 수 있습니다. ID가 있다면를 사용하면 더 쉬울 것입니다 getElementById. 그럼에도 불구하고,

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

그런 다음 querySelectorAll부모 <div>를 사용 div하여 클래스와 일치하는 모든을 가져올 수 있습니다.progress__marker

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

querySelectorAlldiv클래스로 모든 것을 가져옵니다progress__marker


1

현대적인 솔루션

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

선적 서류 비치


0

ES6 2018 년 6 월 업데이트

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

-2

흠. 예제는 IE8에서 작동하지만 객체에 적용하는 경우에는 작동하지 않을 수 있습니다. 필자의 경우 doc을 yui dom 객체로 설정 한 다음 doc.getElementsByClassName을 사용하십시오. 그때가 실패합니다. 편집 : 또는 어쩌면 그 객체가 어떻게 작동하는지 이해하지 못하고 정상적인 dom 객체입니까?
spyderman4g63

@ spyderman4g63의 YUI 버전 getElementsByClassName은의 방법입니다 YAHOO.util.Dom. 귀하의 경우 전화는 다음과 같습니다 YAHOO.util.Dom.getElementsByClassName('four', 'span', 'test'). 해당 통화가 수행하는 작업에 대한 자세한 내용을 이해하려면 문서를 읽어야합니다. 짧은 버전은 지금 찾을 것입니다 span클래스와 요소 four와 DOM 요소 아래 test의로 id.
행크 게이

@ spyderman4g63 예, get호출 결과 는 DOM 요소 일뿐입니다. YUI는 jQuery와 같은 일종의 전체 판매 '프레임 워크 특정 객체로 모든 것을 감싸는'접근 방식을 취하지 않으며 프로토 타입과 같은 기본 객체를 원숭이 패치하지도 않습니다 (Protoype로 엉망이되지 않았습니다) 영원히). 이와 관련하여 YUI는 Dojo와 비슷합니다.
행크 게이

-3

다음은 YUI 선택기를 사용하여 수행 한 방법입니다. Hank Gay의 제안에 감사드립니다.

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

여기서 four = classname, span = 요소 유형 / 태그 이름, test = 부모 ID


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.