직접 대 위임-jQuery .on ()


159

jQuery .on () 메소드를 사용하여 직접위임 된 이벤트 핸들러 의이 특별한 차이점을 이해하려고합니다 . 특히이 단락의 마지막 문장은 다음과 같습니다.

A는 경우 selector제공되는 이벤트 핸들러라고 위임 . 이벤트가 바운드 요소에서 직접 발생할 때 핸들러가 호출되지 않고 선택자와 일치하는 하위 항목 (내부 요소)에 대해서만 호출됩니다. jQuery는 이벤트 대상에서 핸들러가 연결된 요소 (즉, 가장 안쪽에서 가장 바깥 쪽 요소)까지 이벤트를 버블 링하고 해당 경로를 따라 선택기와 일치하는 요소에 대해 핸들러를 실행합니다.

"요소에 대한 핸들러를 실행"한다는 것은 무엇을 의미합니까? 개념을 실험하기 위해 테스트 페이지 를 만들었습니다 . 그러나 다음 두 가지 구성 모두 동일한 동작을 유발합니다.

$("div#target span.green").on("click", function() {
   alert($(this).attr("class") + " is clicked");
});

또는,

$("div#target").on("click", "span.green", function() {
   alert($(this).attr("class") + " is clicked");
});

어쩌면 누군가 가이 점을 분명히하기 위해 다른 예를 참조 할 수 있습니까? 감사.


7
관심있는 모든 사람 : jsperf.com/jquery-fn-on-delegate-vs-direct
dgo

1
@KevinWheeler 나는 아래의 바이올린에 대해 언급했지만 여기 에서는 본질적으로 올바르게 설정되지 않았습니다 (부모 요소에 바인딩하고 위임은 어린이를 대상으로 함). 귀하의 질문에 대답하는 것은 위임 된 처리기가 위임되지 않은 새로 추가 된 요소와 일치한다는 것을 의미합니다. 위임은 브라우저에 연결된 이벤트가 적어 앱의 메모리 소비를 낮추는 이점이 있지만 클릭을 처리하는 시간을 최소화한다는 단점이 있습니다 (최소). 게임을하고 있다면 위임하지 마십시오.
vipero07

1
참조한 "테스트 페이지"가 ​​작동하지 않습니다.
Jaime Montoya

답변:


373

사례 1 (직접) :

$("div#target span.green").on("click", function() {...});

== 야! div # target 내의 모든 span.green을 청취하기를 원합니다. 클릭하면 X를 수행하십시오.

사례 2 (위임) :

$("div#target").on("click", "span.green", function() {...});

== 안녕하세요, div # target! "span.green"인 하위 요소를 클릭하면 X를 사용하십시오.

다시 말해...

사례 1의 경우, 각 범위에 개별적으로 지침이 제공되었습니다. 새로운 스팬이 생성되면 지침을 듣지 못하고 클릭에 응답하지 않습니다. 각 범위는 직접 책임 자체 이벤트를 합니다.

사례 2에서는 컨테이너에만 지시가 주어졌다. 하위 요소 를 대신하여 클릭을 감지해야합니다 . 이벤트 잡기 작업이 위임 되었습니다 . 이것은 또한 미래에 생성되는 하위 요소에 대해 지시가 수행 될 것임을 의미합니다.


45
그것은 훌륭한 설명이며, 오랫동안 이해하기를 거부 한 문제를 명확하게 해주었습니다. 감사!
dgo

3
그렇다면 왜 on()두 개의 인수를 허용 click()합니까?
nipponese

5
.on ()은 여러 다른 이벤트를 포함하여 모든 종류의 이벤트를 처리 할 수있는 범용 API입니다 (첫 번째 문자열에 여러 이벤트 이름을 넣을 수 있습니다.) .click ()은 첫 번째 형식의 약어입니다.
N3dst4

1
@newbie, @ N3dst4 : e.targetclick 이벤트의 초기 대상이됩니다 (자식이있는 경우 자식 노드 일 수 있음 span.green). 핸들러 내부에서 this참조를 사용해야합니다 . 이 바이올린을 참조하십시오 .
LeGEC

1
위임 주제에 추가해야 할 또 다른 참고 사항-매우 유용하고 효율적입니다. 모든 일치하는 요소에 이벤트를 연결하는 것보다 위임을 통해 더 적은 브라우저 리소스를 사용하게됩니다. 사람들이 위임을 사용해야 할 더 많은 이유가 필요한 경우를 대비하여 언급 할 것이라고 생각했습니다.
phatskat

6

첫 번째 방법은 $("div#target span.green").on() 은 클릭 핸들러를 코드가 실행되는 순간 선택기와 일치하는 범위에 직접 바인딩합니다. 이것은 다른 범위가 나중에 추가되거나 클래스가 일치하도록 변경되면 누락되고 클릭 처리기가 없다는 것을 의미합니다. 또한 나중에 클릭 핸들러가 계속 실행되는 범위 중 하나에서 "녹색"클래스를 제거하면 jQuery는 핸들러가 할당 된 방식을 추적하지 않고 선택기가 여전히 일치하는지 확인합니다.

두 번째 방법 $("div#target").on()은 클릭 핸들러를 일치하는 div에 다시 바인딩합니다 (다시 말하면이 시점에서 일치하는 것들에 대한 것임). 클릭이 div에서 발생하면 핸들러 함수는 클릭이 발생한 경우에만 실행됩니다 div뿐만 아니라 두 번째 매개 변수의 선택기와 .on()"span.green"과 일치하는 하위 요소에서 발생했습니다 . 이러한 방식으로 완료되면 해당 하위 범위가 작성된시기는 중요하지 않습니다. 이러한 하위 범위를 클릭하면 핸들러가 계속 실행됩니다.

따라서 내용을 동적으로 추가하거나 변경하지 않는 페이지의 경우 두 방법의 차이점을 알 수 없습니다. 추가 하위 요소를 동적으로 추가하는 경우 두 번째 구문은 상위에서 한 번 수행했기 때문에 클릭 핸들러를 지정하는 것에 대해 걱정할 필요가 없음을 의미합니다.


5

N3dst4에 대한 설명은 완벽합니다. 이를 바탕으로 모든 하위 요소가 본문 안에 있다고 가정 할 수 있으므로 다음과 같이 사용해야합니다.

$('body').on('click', '.element', function(){
    alert('It works!')
});

직접 또는 위임 이벤트와 함께 작동합니다.


2
jquery는 body가 느리기 때문에 body를 사용하지 말 것을 권장합니다. 왜냐하면 스크립트는 body 내부의 모든 자식을 검색해야하기 때문에 대부분의 경우 많이 필요합니다. 요소의 중간 부모 컨테이너를 사용하는 것이 좋습니다.
mikesoft

1
Jquery는 당신이 보여준 것과 같은 라이브 방법을 제거했습니다. 성능이 약하므로 사용해서는 안됩니다.
Maciej Sikora

최신 브라우저에서 $('body').on()위임 은 콜백에서 와 .element기본적 document.body.addEventHandler()으로 동일하게 작동해야합니다 if (Event.target.className.matches(/\belement\b/)). $.proxy오버 헤드 로 인해 jquery에서 약간 느려질 수 있지만 인용하지는 마십시오.
cowbert

2

OP와 접할 수 있지만이 기능과 혼동을 풀기위한 개념 은 바운드 요소가 선택된 요소의 부모 여야한다는 것 입니다.

  • 바운드는 왼쪽의 내용을 나타냅니다 .on .
  • 선택은의 두 번째 인수를 나타냅니다 .on().

바인딩은 바인딩 된 요소의 하위 집합을 선택하는 .find ()처럼 작동하지 않습니다. 선택기는 엄격한 자식 요소에만 적용됩니다.

$("span.green").on("click", ...

~와는 매우 다릅니다

$("span").on("click", ".green", ...

특히, "나중에 생성되는 요소들"에 대한 @ N3dst4 힌트의 이점을 얻으려면 바운드 요소는 영구적 인 부모 여야합니다 . 그런 다음 선택된 아이들이왔다 갔다 할 수 있습니다.

편집하다

위임 .on이 작동하지 않는 이유 점검 목록

$('.bound').on('event', '.selected', some_function)작동하지 않는 까다로운 이유 :

  1. 바운드 요소는 영구적 이지 않습니다 . 전화 후 만들어졌습니다.on()
  2. 선택된 요소는 바인딩 된 요소 의 올바른 자식 이 아닙니다 . 같은 요소입니다.
  3. 선택된 요소 는을 (를) 호출하여 바운드 요소에 대한 이벤트 버블 링 을 방지 했습니다 .stopPropagation().

(맞춤법이 틀린 셀렉터와 같이 까다로운 이유는 생략합니다.)


1

직접 행사를 비교하고 위임 한 게시물을 작성했습니다. 순수한 js를 비교하지만 jquery와 동일한 의미를 가지며 캡슐화합니다.

결론은 위임 된 이벤트 처리는 사용자가 페이지와 상호 작용하는 동안 바인드 된 요소를 만들 수있는 동적 DOM 구조에 대한 것이며 (구조가 변경되지 않음을 알 때 정적 DOM 요소에 대한 직접 이벤트 처리)입니다.

자세한 정보 및 전체 비교-http: //maciejsikora.com/standard-events-vs-event-delegation/

항상 최신 유행 인 위임 된 처리기를 사용하는 것은 올바른 방법이 아니며 많은 프로그래머가 "사용해야"하기 때문에이를 사용하지만 실제로는 직접 이벤트 처리기가 어떤 상황에서는 더 좋으며 방법 사용을 지원해야하는 선택이 더 좋습니다 차이점에 대한 지식으로.


많은 이벤트 처리기 (예 : 테이블의 각 행)를 연결하는 경우 많은 직접 처리기를 연결하는 대신 단일 위임 된 처리기를 컨테이너에 사용하는 것이 성능이 더 좋습니다. 이벤트 핸들러 수 자체가 프로파일 링 메트릭이라는 기본 사실에서이를 확인할 수 있습니다.
cowbert
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.