jQuery : 동일한 이벤트에 대한 둘 이상의 핸들러


137

동일한 요소에 대해 두 개의 이벤트 핸들러를 동일한 이벤트에 바인딩하면 어떻게됩니까?

예를 들면 다음과 같습니다.

var elem = $("...")
elem.click(...);
elem.click(...);

마지막 처리기가 "승리"됩니까, 아니면 두 처리기가 모두 실행됩니까?

답변:


168

두 핸들러가 모두 실행되며 jQuery 이벤트 모델은 하나의 요소에서 여러 핸들러를 허용하므로 이후 핸들러는 이전 핸들러를 대체하지 않습니다.

핸들러는 바인딩 된 순서대로 실행됩니다 .


1
기본 방식은 어떻게됩니까? 그리고 원주민은 특정 것을 제거하는 방법을 어떻게 알 수 있습니까?
SuperUberDuper

1
DOM 레벨 3 (HTML 5 스펙 참조)에 따르면, 이벤트 핸들러는 등록 된 순서대로 실행됩니다 -w3.org/TR/DOM-Level-3-Events/#event-phasew3.org/TR/ 2014 / REC-html5-20141028 / ... . 등록 된 핸들러에 대한 참조를 전달하여 이벤트 핸들러를 제거 할 수 있습니다.
Russ Cam

@RussCam 만약 같은 핸들러가 한번 더 바인딩되면 jQuery('.btn').on('click',handlerClick);실제로는 아무 .off데도 없이 여러 곳에서 호출 된다고 말할 수 있습니까?
techie_28

jQueryUI widgetfactory 위젯의 경우 핸들러를 옵션으로 설정 한 경우에는 해당되지 않습니다. 이전 핸들러와 새 핸들러를 모두 호출하려면 bind메소드 를 사용해야합니다 . 자세한 내용은 다음을 참조하십시오 : learn.jquery.com/jquery-ui/widget-factory/…
Michael Scheper 1

@MichaelScheper는 자유롭게 답변을 수정하고 추가 정보로 업데이트하십시오
Russ Cam

36

두 개의 핸들러 fg 가 있고 알려진 순서와 고정 된 순서로 실행되도록하려면 다음과 같이 캡슐화하십시오.

$("...").click(function(event){
  f(event);
  g(event);
});

이 방법으로 (jQuery의 관점에서) 지정된 순서로 fg 를 호출하는 하나의 핸들러 만 있습니다.


3
+1, 함수 안에 캡슐화하는 방법입니다. 또한 더 나은 조건부 논리가 핸들러 함수 내에 포함되어 트리거되는 이벤트를 제어 할 수 있습니다.
Gordon Potter

시퀀스가 프로그래밍 방식으로 결정되는 처리기 모음입니다.
Aaron Blenkush

17

jQuery의 .bind ()는 바인딩 된 순서대로 실행됩니다 .

이벤트가 요소에 도달하면 요소의 해당 이벤트 유형에 바인딩 된 모든 핸들러가 시작됩니다. 여러 개의 핸들러가 등록되어 있으면 항상 바인딩 된 순서대로 실행됩니다. 모든 핸들러가 실행 된 후 이벤트는 일반 이벤트 전파 경로를 따라 계속됩니다.

출처 : http://api.jquery.com/bind/

jQuery의 다른 함수 (예 :) .click()가 바로 가기 이기 때문에 .bind('click', handler)바인딩 된 순서대로 트리거되는 것으로 추측됩니다.


11

체인을 사용하여 이벤트를 순서대로 실행할 수 있어야합니다. 예 :

$('#target')
  .bind('click',function(event) {
    alert('Hello!');
  })
  .bind('click',function(event) {
    alert('Hello again!');
  })
  .bind('click',function(event) {
    alert('Hello yet again!');
  });

아래 코드가 동일하게 작동하는 것 같습니다.

$('#target')
      .click(function(event) {
        alert('Hello!');
      })
      .click(function(event) {
        alert('Hello again!');
      })
      .click(function(event) {
        alert('Hello yet again!');
      });

출처 : http://www.peachpit.com/articles/article.aspx?p=1371947&seqNum=3

TFM 은 또한 다음과 같이 말합니다.

이벤트가 요소에 도달하면 요소의 해당 이벤트 유형에 바인딩 된 모든 핸들러가 시작됩니다. 여러 개의 핸들러가 등록되어 있으면 항상 바인딩 된 순서대로 실행됩니다. 모든 핸들러가 실행 된 후 이벤트는 일반 이벤트 전파 경로를 따라 계속됩니다.


1
이 코드 나 기사는 핸들러 실행 순서를 정의하지 않습니다. 예, 이것이 이벤트 바인딩 이 발생하는 순서이지만 이벤트 핸들러가 호출되는 순서는 여전히 공식적으로 정의되어 있지 않습니다.
Crescent Fresh

응? "click 이벤트가 발생하면 첫 번째 이벤트 핸들러가 호출되고 두 번째 이벤트 처리기가 호출되고 세 번째 이벤트 처리기가 호출됩니다." 불분명합니까?
anddoutoi

그리고 네, 공식 기록이 이것을 정의하지 않으며 PPK는 이미 이벤트 실행이 무작위임을 입증했지만 jQuery가 이것을 수정했을 것입니다 ^^
anddoutoi

아, 그 문장을 놓쳤다. 실제로 저자는 잘못 알고 있습니다. jQuery는 이것을 "수정"하지 않았다. 사양은 공식적으로 주문을 정의하지 않으므로 기술적으로 수정할 필요가 없습니다.
Crescent Fresh

5
@CrescentFresh : 죄송합니다 같은 늦은 응답을, 난 그냥 질문을했다,하지만 난에 지점을 원하는 링크 , 그것은 jQuery를 공식 문서이며 그것은 분명히 말한다When an event reaches an element, all handlers bound to that event type for the element are fired. If there are multiple handlers registered, they will always execute in the order in which they were bound. After all handlers have executed, the event continues along the normal event propagation path.
Razort4x

2

두 핸들러 모두 호출됩니다.

인라인 이벤트 바인딩 (예 :)을 생각할 수 있습니다 "onclick=...". 큰 단점은 이벤트에 대해 하나의 핸들러 만 설정 될 수 있습니다.

jQuery는 DOM 레벨 2 이벤트 등록 모델을 준수합니다 .

DOM 이벤트 모델을 사용하면 단일 EventTarget에서 여러 이벤트 리스너를 등록 할 수 있습니다. 이를 위해 이벤트 리스너는 더 이상 속성 값으로 저장되지 않습니다.


@Rich : 주문이 공식적으로 정의되지 않았습니다.
Crescent Fresh

2

Stephan202의 캡슐화 및 여러 이벤트 리스너라는 두 가지 방법을 사용하여 성공적으로 작동했습니다. 3 개의 검색 탭이 있는데 입력 텍스트 ID를 배열로 정의하십시오.

var ids = new Array("searchtab1", "searchtab2", "searchtab3");

searchtab1의 내용이 변경되면 searchtab2 및 searchtab3을 업데이트하고 싶습니다. 캡슐화를 위해 이런 식으로 했습니까?

for (var i in ids) {
    $("#" + ids[i]).change(function() {
        for (var j in ids) {
            if (this != ids[j]) {
                $("#" + ids[j]).val($(this).val());
            }
        }
    });
}

여러 이벤트 리스너 :

for (var i in ids) {
    for (var j in ids) {
        if (ids[i] != ids[j]) {
            $("#" + ids[i]).change(function() {
                $("#" + ids[j]).val($(this).val());
            });
        }
    }
}

나는 두 가지 방법을 모두 좋아하지만 프로그래머는 캡슐화를 선택했지만 여러 이벤트 리스너도 작동했습니다. Chrome을 사용하여 테스트했습니다.


1

하나의 핸들러가 다음에 발생하도록 보장하는 해결 방법이 있습니다. 두 번째 핸들러를 포함하는 요소에 첨부하고 이벤트가 버블 링되도록하십시오. 컨테이너에 연결된 핸들러에서 event.target을보고 관심이있는 경우 무언가를 수행 할 수 있습니다.

조잡하지만 어쩌면 효과가 있습니다.


0

jquery는 여러 이벤트 핸들러를 허용하므로 두 핸들러를 모두 실행합니다. 샘플 코드를 만들었습니다. 당신은 그것을 시도 할 수 있습니다

데모

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