수색…


비고

jQuery는 내부적으로 addEventListener 함수를 통해 이벤트를 처리합니다. 즉, 동일한 DOM 요소에 대해 동일한 이벤트에 둘 이상의 함수가 바인드되는 것은 완전히 합법적입니다.

이벤트 처리기 연결 및 분리

이벤트 처리기 연결

버전 1.7 부터 jQuery에는 이벤트 API .on() 있습니다. 이 방법으로 모든 표준 자바 스크립트 이벤트 또는 사용자 정의 이벤트를 현재 선택된 jQuery 요소에 바인딩 할 수 있습니다. .click() 과 같은 바로 가기가 있지만 .click() .on() 은 더 많은 옵션을 제공합니다.


HTML

<button id="foo">bar</button>

jQuery

$( "#foo" ).on( "click", function() {
  console.log( $( this ).text() ); //bar
});

이벤트 처리기 분리

물론 jQuery 객체에서도 이벤트를 분리 할 수 ​​있습니다. .off( events [, selector ] [, handler ] ) 됩니다.


HTML

<button id="hello">hello</button>

jQuery

$('#hello').on('click', function(){
    console.log('hello world!');
    $(this).off();
});

$(this) 버튼을 클릭하면 현재 jQuery 객체를 참조하고 연결된 모든 이벤트 핸들러를 제거합니다. 제거 할 이벤트 핸들러를 지정할 수도 있습니다.

jQuery

$('#hello').on('click', function(){
    console.log('hello world!');
    $(this).off('click');
});

$('#hello').on('mouseenter', function(){
    console.log('you are about to click');
});

이 경우 클릭 한 후 mouseenter 이벤트가 계속 작동합니다.

위임 된 이벤트

예를 들어 설명해 보겠습니다. 다음은 간단한 HTML 예제입니다.

HTML 예제

<html>
    <head>
    </head>
    <body>
        <ul>
            <li>
                <a href="some_url/">Link 1</a>
            </li>
            <li>
                <a href="some_url/">Link 2</a>
            </li>
            <li>
                <a href="some_url/">Link 3</a>
            </li>
        </ul>
    </body>
</html>

문제

이제이 예제에서 모든 <a> 요소에 이벤트 리스너를 추가하려고합니다. 문제는이 예제의 목록이 동적이라는 것입니다. <li> 시간이 지날수록 요소가 추가되고 제거됩니다. 그러나 페이지는 변경 사항 사이에서 새로 고침되지 않으므로 간단한 클릭 이벤트 리스너 (예 : $('a').click() )를 링크 개체에 사용할 수 있습니다.

우리가 가진 문제는오고가는 <a> 요소에 이벤트를 추가하는 방법입니다.


배경 정보 - 이벤트 전달

위임 된 이벤트는 이벤트 전파 (이벤트 버블 링이라고도 함) 때문에 만 가능합니다. 이벤트가 발생하면 항상 문서 루트로 이동합니다. 그들은 비 변화 조상 요소에 따라서 이름이 "위임"이벤트를 이벤트의 처리를 위임합니다.

위의 예에서 <a> 요소 링크를 클릭하면 다음 요소에서 '클릭'이벤트가 발생합니다.

  • 에이
  • ul
  • 신체
  • HTML
  • 문서 루트

해결책

버블 링 이벤트가 무엇인지 알면 HTML을 통해 전파되는 원하는 이벤트 중 하나를 잡을 수 있습니다.

이 예제에서 그것을 잡는 좋은 장소는 <ul> 요소인데, 그 요소는 동적 요소가 아니기 때문이다.

$('ul').on('click', 'a', function () {
  console.log(this.href); // jQuery binds the event function to the targeted DOM element
                          // this way `this` refers to the anchor and not to the list
  // Whatever you want to do when link is clicked
});

위 :

  • 이 이벤트 리스너의 수신자 인 'ul'이 있습니다.
  • 첫 번째 매개 변수 ( 'click')는 탐지하려는 이벤트를 정의합니다.
  • 두 번째 매개 변수 ( 'a')는 이벤트가 발생한 위치를 선언하는 데 사용됩니다 (이 이벤트 수신기의받는 사람 ul 아래에있는 모든 자식 요소 중에서).
  • 마지막으로 세 번째 매개 변수는 첫 번째 및 두 번째 매개 변수의 요구 사항이 충족되면 실행되는 코드입니다.

솔루션의 작동 방식에 대해 자세히 설명합니다.

  1. 사용자가 <a> 요소를 클릭합니다.
  2. 그러면 <a> 요소에서 click 이벤트가 트리거됩니다.
  3. 이 이벤트는 문서 루트쪽으로 버블 링을 시작합니다.
  4. 이 이벤트는 먼저 <li> 요소와 <ul> 요소로 <ul> .
  5. <ul> 요소에 이벤트 수신기가 연결되어 있으므로 이벤트 수신기가 실행됩니다.
  6. 이벤트 리스너는 먼저 트리거링 이벤트를 감지합니다. 버블 링 이벤트는 '클릭'이고, 청취자는 '클릭', 즉 통과입니다.
  7. 리스너 검사는 두 번째 매개 변수 ( 'a')를 버블 체인의 각 항목과 일치 시키려고 시도합니다. 체인의 마지막 항목이 'a'이므로 필터와 일치하며 이는 역시 패스입니다.
  8. 세 번째 매개 변수의 코드는 그것의로 일치하는 항목을 사용하여 실행 this . 함수에 stopPropagation() 대한 호출이 포함되어 있지 않으면 이벤트는 루트 ( document )쪽으로 위쪽으로 계속 전파됩니다.

참고 : 변경되지 않는 적절한 조상을 사용할 수 없거나 편리하지 않은 경우 document 를 사용해야 document . 습관 때문에 다음과 같은 이유로 'body' 을 사용하지 마십시오.

  • body 에는 스타일링과 관련된 버그가 있습니다. 이는 마우스 이벤트가 거품을 일으키지 않는 것을 의미 할 수 있습니다. 이것은 브라우저에 따라 다르며 계산 된 몸체 높이가 0 일 때 (예 : 모든 자식 요소가 절대 위치를 가질 때) 발생할 수 있습니다. 마우스 이벤트는 항상 documentdocument .
  • document 항상 스크립트에 있으므로, 위임 된 핸들러를 DOM 준비 핸들러 외부에서 document 첨부 할 수 있으며 여전히 작동 할 것임을 확신 할 수 있습니다.

문서로드 이벤트 .load ()

이미지 나 PDF와 같은 특정 리소스가로드 될 때까지 스크립트를 대기 시키려면 .load() .on( "load", handler) 대한 바로 가기의 바로 가기 인 .load() 사용할 수 있습니다.

HTML

<img src="image.jpeg" alt="image" id="image">

jQuery

$( "#image" ).load(function() {
  // run script
});

ID를 사용하지 않고 반복되는 요소에 대한 이벤트

문제

특정 인스턴스로 어떤 작업을 수행하기 위해 어떤 이벤트가 발생했는지 알아야하는 일련의 반복 요소가 페이지에 있습니다.

해결책

  • 모든 공통 요소에 공통 클래스 부여
  • 이벤트 리스너를 클래스에 적용합니다. this 내부 이벤트 핸들러는 이벤트가 발생한 일치하는 selector 요소입니다.
  • 이 인스턴스를 시작 this 인스턴스에 대해 가장 바깥 쪽 반복 컨테이너로 이동 this
  • 해당 컨테이너 내에서 find() 사용하여 해당 인스턴스와 관련된 다른 요소를 분리합니다.

HTML

<div class="item-wrapper" data-item_id="346">
   <div class="item"><span class="person">Fred</span></div>
   <div class="item-toolbar">
      <button class="delete">Delete</button>
   </div>   
</div>
<div class="item-wrapper" data-item_id="393">
   <div clss="item"><span class="person">Wilma</span></div>
   <div class="item-toolbar">
      <button class="delete">Delete</button>
   </div>   
</div>

jQuery

$(function() {
  $('.delete').on('click', function() {
    // "this" is element event occured on
    var $btn = $(this);
    // traverse to wrapper container
    var $itemWrap = $btn.closest('.item-wrapper');
    // look within wrapper to get person for this button instance
    var person = $itemWrap.find('.person').text();
    // send delete to server and remove from page on success of ajax
    $.post('url/string', { id: $itemWrap.data('item_id')}).done(function(response) {
      $itemWrap.remove()
    }).fail(function() {
      alert('Ooops, not deleted at server');
    });
  });
});

originalEvent

때로는 jQuery 이벤트에서 사용할 수없는 속성이있을 수 있습니다. 기본 속성에 액세스하려면 Event.originalEvent 사용 Event.originalEvent

스크롤 방향 가져 오기

$(document).on("wheel",function(e){
    console.log(e.originalEvent.deltaY)
    // Returns a value between -100 and 100 depending on the direction you are scrolling
})

jQuery를 통해 특정 이벤트를 켜거나 끕니다. (명명 된 수신기)

때로는 이전에 등록 된 리스너를 모두 끄고 싶을 때가 있습니다.

//Adding a normal click handler
$(document).on("click",function(){
    console.log("Document Clicked 1")
});
//Adding another click handler
$(document).on("click",function(){
    console.log("Document Clicked 2")
});
//Removing all registered handlers.
$(document).off("click")

이 방법의 문제점은 다른 플러그인에 의해 document 에 바인딩 된 모든 리스너가 제거된다는 것입니다.

종종 우리는 우리에 의해서만 연결된 모든 청취자를 분리하고자합니다.

이것을 실현하기 위해 (때문에), 이름 첨부 청취자를 바인드 해,

//Add named event listener.
$(document).on("click.mymodule",function(){
    console.log("Document Clicked 1")
});
$(document).on("click.mymodule",function(){
    console.log("Document Clicked 2")
});

//Remove named event listener.
$(document).off("click.mymodule");

이렇게하면 다른 클릭 리스너가 우연히 수정되지 않도록 할 수 있습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow