programing

getElementsByClassName을 통해 올바르게 반복하는 방법

iphone6s 2023. 7. 26. 21:42
반응형

getElementsByClassName을 통해 올바르게 반복하는 방법

저는 자바스크립트 초보자입니다.

는 웹페지시중다니입는하작를을 통해 웹 를 시작하고 있습니다.window.onload을 클래스.slide 및 일부 다른 및 일부 논리에 따라 다른 노드로 재배포합니다.나는 기능이 있습니다.Distribute(element)요소를 입력으로 사용하여 분포를 수행합니다.다음과 같은 작업을 수행하고 싶습니다(: 여기 또는 여기에서 설명).

var slides = getElementsByClassName("slide");
for(var i = 0; i < slides.length; i++)
{
   Distribute(slides[i]);
}

하지만 이것은 나에게 마법을 부리지 않습니다, 왜냐하면getElementsByClassName실제로 배열을 반환하는 것이 아니라 a, 즉...

...이것이 제 추측입니다...

...기능 내부에서 변경 중입니다.Distribute(DOM 트리는 이 함수 내에서 변경되고 있으며 특정 노드의 복제가 발생합니다.)For-each루프 구조도 도움이 되지 않습니다.

가변 슬라이드는 정말 비결정론적으로 작용합니다. 반복할 때마다 요소의 길이와 순서가 크게 바뀝니다.

이 경우 NodeList를 통해 반복하는 올바른 방법은 무엇입니까?임시 배열을 채울까 생각 중이었는데, 어떻게 해야 할지 모르겠어요...

편집:

하는 것을 다른 슬라이드 입니다. 이 슬라이드를 입니다. 이것이 실제로 변화하는 것입니다.slides사용자 Alohci 덕분에 방금 알게 된 변수입니다.

솔루션은 먼저 각 요소를 어레이로 복제하고 어레이를 하나씩 전달하는 것이었습니다.Distribute()

MDN에 따르면, 아이템을 검색하는 방법은NodeList다음과 같습니다.

nodeItem = nodeList.item(index)

따라서:

var slides = document.getElementsByClassName("slide");
for (var i = 0; i < slides.length; i++) {
   Distribute(slides.item(i));
}

적이 .for루프는 항상 나에게 효과가 있었다), 하지만 시도해 보세요.

새 쿼리를 사용하는 경우 선택기각 사용자가 직접 호출할 수 있는 모든 것.

document.querySelectorAll('.edit').forEach(function(button) {
    // Now do something with my button
});

아래 설명에 따라.nodeLists에는 각 함수에 대한 값이 없습니다.

이것을 바벨과 함께 사용하면 추가할 수 있습니다.Array.from노드가 아닌 목록을 각 배열에 대해 a로 변환합니다.Array.from11을 . IE 11은 기본적으로 작동하지 않습니다.

Array.from(document.querySelectorAll('.edit')).forEach(function(button) {
    // Now do something with my button
});

어젯밤 미팅에서 각 노드에 대한 노드 목록이 없는 다른 방법을 발견했습니다.

[...document.querySelectorAll('.edit')].forEach(function(button) {
    // Now do something with my button
});

[...]에 대한 브라우저 지원

노드 목록으로 표시

Showing as Node List

배열로 표시

Showing as Array

2021년 최신 답변

.getElementsBy*메서드는 NodeList가 아닌 라이브 HTMLCollection을 반환합니다.getElementsByName

이 두 목록 사이에는 현저한 차이가 있습니다.두메소드가 에는 HTMLCollection과 를 포함한 다섯.NodeList.forEach노드 목록을 통해 반복하는 데 사용할 수 있습니다.

실시간 수집은 후드 아래에서 수집을 업데이트할 수 있는 방법이 없기 때문에 문제가 있습니다.신뢰할 수 있는 컬렉션을 얻기 위해 현재 HTMLCollection의 모든 구현에서 컬렉션에 액세스할 때마다 DOM을 통과합니다.실제로 이는 길이를 포함하여 실시간 컬렉션의 구성원에 액세스할 때마다 브라우저가 전체 문서를 순회하여 특정 요소를 찾는다는 것을 의미합니다.

표준은 다음과 같습니다.

컬렉션이 활성 상태이면 해당 개체의 특성과 메서드가 데이터 스냅샷이 아닌 실제 기본 데이터에서 작동해야 합니다.

라이브 HTMLCollection을 반복하지 마십시오!

대신 컬렉션을 어레이로 변환하고 해당 어레이를 반복합니다.또는 정적 노드 목록과 보다 유연한 요소 선택 방법을 제공하는 를 사용하여 요소를 가져오십시오.

요소의 실시간 목록이 정말로 필요한 경우 다음 대신 가능한 가장 가까운 공통 조상 요소를 컨텍스트로 사용합니다.document.

주목할 점은 라이브 노드 목록도 존재한다는 것입니다.활성 노드 목록의 예로는 Node.childNodesgetElementsByName의 반환 값이 있습니다.

항상 배열 방법을 사용할 수 있습니다.

var slides = getElementsByClassName("slide");
Array.prototype.forEach.call(slides, function(slide, index) {
    Distribute(slides.item(index));
});

2022년 업데이트

가장 빠르고 짧은 솔루션

[...document.getElementsByClassName('className')].forEach(el => {
    // Do something with each element
})

왜 작동합니까?

라이브 HTML 수집을 반복하는 것은 매우 비효율적입니다.

에 sticks의 답변에서 언급한 바와 같이,[...htmlCollection]클래스 집합을 배열로 변환합니다.라이브 HTMLCollection을 직접 반복하는 것은 매우 비효율적이기 때문에 어레이로 변환해야 합니다.teemu는 위에서 "라이브 HTMLCollection을 반복하지 않습니다!":

실시간 수집은 후드 아래에서 수집을 업데이트할 수 있는 방법이 없기 때문에 문제가 있습니다.신뢰할 수 있는 컬렉션을 얻기 위해 현재 HTMLCollection의 모든 구현에서 컬렉션에 액세스할 때마다 DOM을 통과합니다.실제로 이는 길이를 포함하여 실시간 컬렉션의 구성원에 액세스할 때마다 브라우저가 전체 문서를 순회하여 특정 요소를 찾는다는 을 의미합니다.

가장 빠르고 효율적인 이유는 무엇입니까?

로 참: 사를 사용합니다.[...arr]htmlCollection을 배열로 변환하는 가장 빠르고 효율적인 방법입니다.harpo가 만든 모든 방법의 성능 비교는 http://jsben.ch/h2IFA 에서 확인할 수 있습니다.

(여기에서 htmlCollection을 배열로 변환하는 것에 대한 모든 세부 정보를 참조하십시오.)

라이브니까 거꾸로 루프하자는 알로치의 권유를 따랐습니다.nodeList호기심 많은 사람들을 위해 제가 한 일은 이렇습니다.

  var activeObjects = documents.getElementsByClassName('active'); // a live nodeList

  //Use a reverse-loop because the array is an active NodeList
  while(activeObjects.length > 0) {
    var lastElem = activePaths[activePaths.length-1]; //select the last element

    //Remove the 'active' class from the element.  
    //This will automatically update the nodeList's length too.
    var className = lastElem.getAttribute('class').replace('active','');
    lastElem.setAttribute('class', className);
  }

+ 루프를 사용할 수 있습니다.

const listA = document.getElementById('A');
const listB = document.getElementById('B');
const listC = document.getElementById('C');
const btn = document.getElementById('btn');

btn.addEventListener('click', e => {
  // Loop & manipulate live nodeLList
  for (const li of Object.values(listA.getElementsByClassName('li'))) {
    if (li.classList.contains('active')) {
      listB.append(li);
    } else {
      listC.append(li);
    }
  }
});
ul {
  display: inline-flex;
  flex-direction: column;
  border: 1px solid;
}

ul::before {
  content: attr(id);
}

.active {
  color: red;
}

.active::after {
  content: " (active)";
}
<ul id="A">
  <li class="li active">1. Item</li>
  <li class="li">2. Item</li>
  <li class="li">3. Item</li>
  <li class="li active">4. Item</li>
  <li class="li active">5. Item</li>
  <li class="li">6. Item</li>
  <li class="li active">7. Item</li>
  <li class="li">8. Item</li>
</ul>

<button id="btn">Distribute A</button>

<ul id="B"></ul>
<ul id="C"></ul>

한 줄:
Object.values(listA.getElementsByClassName('li')).forEach(li => (li.classList.contains('active') ? listB : listC).append(li))

다음은 각 클래스에 임의의 번호를 할당하기 위해 수행한 예입니다.

var a = $(".className").length;
for(var i = 0; i < a; i++){
    var val = $(".className")[i];
    var rand_ = (Math.random()*100).toFixed(0);
    $(val).val(rand_);
}

참고용일 뿐입니다.

 <!--something like this--> 
<html>
<body>



<!-- i've used for loop...this pointer takes current element to apply a 
 particular change on it ...other elements take change by else condition 
-->  


<div class="classname" onclick="myFunction(this);">first</div>  
<div class="classname" onclick="myFunction(this);">second</div>


<script>
function myFunction(p) {
 var x = document.getElementsByClassName("classname");
 var i;
 for (i = 0; i < x.length; i++) {
    if(x[i] == p)
    {
x[i].style.background="blue";
    }
    else{
x[i].style.background="red";
    }
}
}


</script>
<!--this script will only work for a class with onclick event but if u want 
to use all class of same name then u can use querySelectorAll() ...-->




var variable_name=document.querySelectorAll('.classname');
for(var i=0;i<variable_name.length;i++){
variable_name[i].(--your option--);
}



 <!--if u like to divide it on some logic apply it inside this for loop 
 using your nodelist-->

</body>
</html>

저도 비슷한 문제가 있어서 여기에 도착했습니다.아마 다른 사람도 저와 같은 실수를 하고 있을 거예요.

저의 경우, 선택기는 전혀 문제가 되지 않았습니다.문제는 제가 자바스크립트 코드를 엉망으로 만들었다는 것입니다.저는 루프와 서브루프를 가지고 있었습니다. 서루프사중입다니용도를 .i대에신 카로서터운서▁as▁of로.j그래서 서브루프가 가치를 무시했기 때문입니다.i메인 루프 중에서, 이 루프는 두 번째 반복에 도달하지 못했습니다.

var dayContainers = document.getElementsByClassName('day-container');
for(var i = 0; i < dayContainers.length; i++) { //loop of length = 2
        var thisDayDiv = dayContainers[i];
        // do whatever

        var inputs = thisDayDiv.getElementsByTagName('input');

        for(var j = 0; j < inputs.length; j++) { //loop of length = 4
            var thisInput = inputs[j];
            // do whatever

        };

    };

쿼리 선택기를 사용하여 간편하고 간편하게 수행

const elements = document.querySelectorAll('.fixed-class-name');
for (let i = 0; i < elements.length; i++) {
  const element = elements[i];
  // Do something with each element
}

언급URL : https://stackoverflow.com/questions/15843581/how-to-correctly-iterate-through-getelementsbyclassname

반응형