querySelectorAll()은 동적 생성, 삭제 요소를 캡처하지 않습니다.

querySelectorAll()은 CSS 선택기의 기법을 통해 여러 요소를 쉽게 얻을 수 있지만 동적으로 대상 요소를 생성하거나 삭제할 때 기술 방법에 따라 결과가 달라진다.

서술의 차이


처리 또는 변수에 저장된 참조의 차이점을 직접 기술합니다.
console.log(document.querySelectorAll('.card'));
const cards = document.querySelectorAll('.card');
console.log(cards);

얻은 결과가 뭐가 달라요?

.card 동적 생성은 유형적인 요소를 가지고 이들의 결과를 비교한다.
샘플 HTML
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>サンプル</title>
  <style>
    *{ box-sizing: border-box; }
    .card{ width: 200px; height: 100px; padding: 5px 0 0 10px; margin-top: 10px; background-color:#dddddd; }
    #card01{ background-color:#e02f2f; }
    #card02{ background-color:#4973f2; }
    #card03{ background-color:#f0e90c; }
    #card04{ background-color:#48f026; }
    .isSemitransparent{ opacity: 0.5; }
  </style>
</head>
<body id="body">
  <div id="cardWrap">
    <div id="card01" class="card">カード1</div>
    <div id="card02" class="card">カード2</div>
    <div id="card03" class="card">カード3</div>
  </div>
  <script>
    // ここに処理を書く
  </script>
</body>
</html>
샘플 HTML의 초기 표시카드 세 장이 나왔어요.

콘솔을 사용한 인증(동적 네 번째 녹색카드 생성)


처리 시 얻은 결과를 직접 기술하다

마지막으로 내보낸 로그에서 NodeList에서 생성된 요소에 대한 정보를 반영합니다.
변수에 저장하고 참조할 때의 결과 얻기

마지막으로 내보낸 로그의 NodeList를 보십시오.4장의 카드가 표시되고 NodeList는 3으로 유지됩니다.생성된 요소에 대한 정보가 반영되지 않았습니다.
변수 참조는 동적으로 생성되고 삭제된 요소를 반영하지 않습니다.

왜 결과가 달라질까요?


MDNNodeList에는 다음과 같은 설명이 있습니다.
document.querySelectorAll() 메서드는 정적 NodeList를 반환합니다.
NodeList에는 정적 동적 개념이 있는 것 같습니다.
나는 아직 정태, 동태의 차이를 완전히 이해하지 못했지만 많은 조사를 한 후에 다음과 같은 설명을 했다.
동적 NodeList...웹 페이지를 구성하는 Node의 NodeList를 참조하는 중
정적 NodeList...웹 페이지를 구성하는 노드 복사(심도 복사)로 만든 NodeList※ 디트로이트 dep-copy 이런 표현은 결국 인상
상기 설명에 따르면 변수에 저장된 정적 NodeList는 처리가 시작되었을 때(변수를 대입한 시간)의 노드에 따라 제작된 복제품이다.대원의 노드와는 관련이 없기 때문에 대원의 노드가 달라져도 영향을 받지 않는다.대입 후 대원 노드가 바뀌면 변수에 저장된 노드리스트는 실제 노드보다 오래된 정보로 바뀐다.

동적 생성, 삭제를 반영하고자 하는 요소


대상 요소가 동태적으로 생성되고 삭제되는 상황, 그리고 이런 요소에 대해 무엇을 하고 싶은지 존재할 수 있다.
처리 방법을 직접 기술할 수 있지만 getElementsBy~() 방법을 사용하는 것도 방법이다.
다음을 전제로 검증하다.
  • 동적 생성 목표 요소
  • 대상의 요소를 클릭하면 투명해짐
  • script 탭에 다음 코드를 기술합니다.
    // getElementsByClassName()で取得したものを変数化
    const cards = document.getElementsByClassName('card');
    
    // cardクラスを持つ要素を生成
    const cardWrap = document.getElementById('cardWrap');
    const card04 = document.createElement('div');
    card04.id = 'card04';
    card04.classList = 'card';
    card04.textContent = 'カード4';
    cardWrap.appendChild(card04, cardWrap);
    
    // for of文でcards内の要素全てにクリックイベントを与えてまわる
    for (let item of cards) {
      item.addEventListener('click', () => {
        event.currentTarget.classList.add('isSemitransparent');
      });
    };
    
    클릭 이벤트도 동적 생성된 녹색카드에 적용됩니다.
    console.log 확인을 통해 get Elements ByClassName () 으로 요소를 가져오면 HTML Collection이 되돌아온다는 것을 알 수 있습니다.
    HTML Collection은 동적이며 실제 노드의 요소를 반영하기 때문에 변수에 저장하여 참고하는 것도 문제없다.
    그나저나 query Selector All()에서 같은 일을 하면 그린카드만 이벤트를 클릭하지 않는다.

    총결산


    querySelectorAll()을 사용할 때 가져올 요소가 동적 처리를 넣었는지 확인하십시오.
    얻을 요소에 동적 처리를 넣은 경우 getelementsBy~()를 사용하는 것이 좋습니다.

    잡담


    jQuery에서 $()에서 요소를 가져올 수 있지만 변수화되면querySelectorAll()과 같은 문제가 발생할 수 있음을 주의해야 합니다.
    또한 JQuery는 $('.card').on('click', function(){ 〜 処理 〜 });라는 기술에서 클릭 이벤트를 모든.card 요소에 적용할 수 있지만 query Selector All()과get Elements By()에서 같은 일을 하고 싶으면 오류를 되돌려줍니다.
    const cards = document.querySelectorAll('.card');
    cards.addEventListener('click', () => {
      event.currentTarget.classList.add('isSemitransparent');
    });
    // => cards.addEventListener is not a function
    
    const cards = document.getElementsByClassName('card');
    cards.addEventListener('click', () => {
      event.currentTarget.classList.add('isSemitransparent');
    });
    // => cards.addEventListener is not a function
    
    이벤트 처리를 추가하는 addEventListener () 방법은 하나의 요소에 유효하지만 원소의 집합에 사용할 수 없습니다.jQuery의 기술에서는 사건 처리를 통일적으로 사용한 것처럼 보이지만 뒷면에서는 for문으로 착실하게 반복 처리했다.
    참조: 왜!?document.querySelectorAll(selector).addEventListener()가 움직이지 않는 이유

    좋은 웹페이지 즐겨찾기