jquery .each ()를 사용하여 개별 이벤트 리스너를 추가하는 방법은 무엇입니까?

Jan 08 2021

간단한 설정 : 다른 값을 가진 두 개의 버튼. jquery의 .each () 함수를 사용하여 각 버튼의 값을 기록하는 각 버튼에 클릭 이벤트 리스너를 추가하고 싶습니다. 그러나 .each ()를 사용할 때 jquery는 이전 버튼에 대한 클릭 핸들러를 덮어 씁니다. 이로 인해 두 가지 질문이 남습니다.

  1. 왜 그런 겁니까?
  2. jquery 객체 모음에 개별 이벤트 리스너를 어떻게 추가합니까?

아래 코드 참조

  <html lang="en">
    
    <head>
        <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
        <script>
            $(() => { $(`button[toggle]`).each((_, button) => {
                    let $toggle = $(button);
                    type = $toggle.attr("type"); value = $toggle.attr("value");
                    $toggle.on("click", () => {
                        console.log(type, value);
                    });
                });
            });
        </script>
    
    </head>
    
    <body>
        <div>
            <button toggle type="one" value="true">One</button>
            <button toggle type="two" value="false">Two</button>
        </div>
    </body>
    
    </html>

답변

1 RoryMcCrossan Jan 08 2021 at 20:14

코드의 문제 는 및 변수를 암시 적으로 선언 했기 때문에 범위 내에 있습니다. 따라서 이후의 각 반복은 값을 덮어 쓰므로 루프가 끝난 후 최종 값만 표시됩니다.typevaluewindow

이를 수정하려면 루프 에서 변수를 정의하십시오 .

$(() => { $(`button[toggle]`).each((_, button) => {
    let $toggle = $(button);
    let type = $toggle.attr("type"); let value = $toggle.attr("value");
    $toggle.on("click", () => {
      console.log(type, value);
    });
  });
});
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<div>
  <button toggle type="one" value="true">One</button>
  <button toggle type="two" value="false">Two</button>
</div>

그러나each() 루프가 전혀 필요하지 않습니다. 동일한 이벤트 핸들러를 모든button요소에 바인딩하고target해당 속성에 액세스하기 위해 발생하는 이벤트의속성을사용하여문제를 해결하고 코드 품질을 개선 할 수 있습니다.

또한 toggle이 경우 고유 한 비표준 속성을 추가 하면 UI 및 JS에 문제가 발생할 수 있습니다. 더 나은 접근 방식은 클래스를 사용하여 요소를 그룹화하는 것입니다.

마지막으로, onetwo에 대한 유효한 값없는 type속성입니다. 용도 data요소에 사용자 정의 메타 데이터를 연결하는 대신 속성을.

말한대로 다음을 시도하십시오.

jQuery($ => {
  $('.toggle').on('click', e => { let $toggle = $(e.target); let type = $toggle.data("type"); 
    let value = $toggle.prop("value");
    console.log(type, value);
  });
});
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<div>
  <button class="toggle" data-type="one" value="true">One</button>
  <button class="toggle" data-type="two" value="false">Two</button>
</div>

1 prasanth Jan 08 2021 at 20:10

$(this)클릭 콜백 내부에서 사용

$(() => {
  $(`button[toggle]`).each((_, button) => { $(button).on("click", function(){
       type   = $(this).attr("type"); value = $(this).attr("value");
      console.log(type, value);
    });
  });
});
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

<button toggle type="one" value="true">One</button>
<button toggle type="two" value="false">Two</button>

또한 각 콜백 내부에 언급 할 필요가 없습니다. 아래와 같이 정상적인 방법으로 전화 할 수 있습니다.

$(() => { $(`button[toggle]`).on("click", function(){
       type   = $(this).attr("type"); value = $(this).attr("value");
      console.log(type, value);
    });
});
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

<button toggle type="one" value="true">One</button>
<button toggle type="two" value="false">Two</button>

Kostas Jan 08 2021 at 20:11
  1. 리스너는 $ toggle의 마지막 값에 바인딩하기 때문입니다.
  2. 스 니펫에 표시된대로 새 함수를 만들고 실행합니다.

이 질문 에서 더 잘 설명했습니다 .

<html lang="en">
    
    <head>
        <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
        <script>
            $(() => {
                $(`button[toggle]`).each((_, button) => { let $toggle = $(button); type = $toggle.attr("type");
                    value = $toggle.attr("value"); $toggle.on("click", ((type, value) => {
                      return () => {
                        console.log(type, value);
                      };
                    })(type, value));
                });
            });
        </script>
    
    </head>
    
    <body>
        <div>
            <button toggle type="one" value="true">One</button>
            <button toggle type="two" value="false">Two</button>
        </div>
    </body>
    
    </html>