Home > Web Front-end > JS Tutorial > jQuery code optimization event delegation_jquery

jQuery code optimization event delegation_jquery

WBOY
Release: 2016-05-16 17:59:48
Original
1007 people have browsed it

jQuery provides .bind(), .live(), and .delegate() methods for binding and delegated events. This article discusses the internal implementation of these methods and shows their advantages, disadvantages and applicable occasions.

Event delegation

Examples of event delegation abound in reality. For example, three colleagues are expected to receive express delivery on Monday. There are two ways to sign for the express delivery: one is to have three people waiting for the express delivery at the door of the company; the other is to entrust the receptionist to sign for it on your behalf. In reality, we mostly use the entrusted solution (the company will not tolerate so many employees standing at the door just waiting for express delivery). After the MM at the front desk receives the express delivery, she will determine who the recipient is, then sign for it according to the recipient's requirements, and even pay for it on her behalf. Another advantage of this solution is that even if new employees come to the company (no matter how many), the front desk MM will verify the express delivery sent to the new employees and sign for it on their behalf.

We know that when the DOM dispatches an event to each element in the page, the corresponding element generally handles the event in the event bubbling stage. In a structure like body > div > a, if you click the a element, the click event will bubble up from a to the div and body (i.e. the document object). Therefore, click events that occur on a, div and body elements can also be handled. By using the mechanism of event propagation (here, bubbling), event delegation can be achieved. Specifically, event delegation means that the event target does not process the event itself, but delegates the processing task to its parent element or ancestor element, or even the root element (document).

.bind()
Suppose there is a table with multiple rows and columns. We want the user to click on each cell to see more information related to the content in it. information (e.g., via a tooltip). To do this, you can bind a click event to each cell:

$("info_table td").bind("click", function(){/*Show more information*/});

The problem is that if there are 10 columns and 500 rows in the table to which click events are bound, then finding and traversing 5000 cells will cause the script to execute significantly slower, while saving 5000 td elements and corresponding The event handler will also take up a lot of memory (similar to having everyone physically stand at the door waiting for a delivery).

Based on the previous example, if we want to implement a simple photo album application, each page only displays thumbnails of 50 photos (50 cells), and the user clicks "Page x" (or "Next Page") link can dynamically load another 50 photos from the server via Ajax. In this case, it seems that binding events for 50 cells using the .bind() method is acceptable again.

That’s not the case. Using the .bind() method will only bind click events to 50 cells on the first page. Cells in subsequent pages that are dynamically loaded will not have this click event. In other words, .bind() can only bind events to elements that already exist when it is called, and cannot bind events to elements that will be added in the future (similar to how new employees cannot receive express delivery).

Event delegation can solve the above two problems. Specific to the code, just use the .live() method added in jQuery 1.3 instead of the .bind() method:

$("#info_table td").live("click",function() {/*Show more information*/});

The .live() method here will bind the click event to the $(document) object (but this cannot be reflected from the code, this is also An important reason why the .live() method has been criticized (will be discussed in detail later), and you only need to bind $(document) once (not 50 times, let alone 5000 times), and then you can handle subsequent dynamic loading. Click event of the photo cell. When receiving any event, the $(document) object will check the event type and event target. If it is a click event and the event target is td, then the handler delegated to it will be executed.

.live()
So far, everything seems to be perfect. Unfortunately, this is not the case. Because the .live() method is not perfect, it has the following major shortcomings: The

$() function will find all td elements in the current page and create jQuery objects, but it is not used when confirming the event target. This collection of td elements instead uses selector expressions to compare with event.target or its ancestor elements, so generating this jQuery object will cause unnecessary overhead;
The event is bound to the $(document) element by default. If the DOM nested structure is very deep, event bubbling through a large number of ancestor elements will cause performance losses;
can only be placed after the directly selected element, and cannot be used after the consecutive DOM traversal method, that is, $("#infotable td ").live... works, but $("#infotable").find("td").live... does not work;
collects td elements and creates jQuery objects, but the actual operation is $( document) object, which is puzzling.

Solution

In order to avoid generating unnecessary jQuery objects, you can use a hack called "early delegation", that is, in $(document).ready () method external call .live():

Copy code The code is as follows:

(function ($){
$("#info_table td").live("click",function(){/*Show more information*/});
})(jQuery);

여기서 (function($){...})(jQuery)는 "즉시 실행되는 익명 함수"로, 이름 충돌을 방지하기 위해 클로저를 형성합니다. 익명 함수 내에서 $parameter는 jQuery 객체를 참조합니다. 이 익명 함수는 DOM이 실행되기 전에 준비될 때까지 기다리지 않습니다. 이 해킹을 사용할 때 스크립트는 페이지의 헤드 요소에서 연결 및/또는 실행되어야 합니다. 이 타이밍을 선택한 이유는 이 시점에서 문서 요소를 사용할 수 있고 전체 DOM이 생성되지 않기 때문입니다. 스크립트가 닫는 body 태그 앞에 배치되면 DOM이 완전히 생성되기 때문에 의미가 없습니다. 그 시간에 사용 가능합니다.

이벤트 버블링으로 인한 성능 손실을 방지하기 위해 jQuery는 1.4부터 .live() 메서드를 사용할 때 컨텍스트 매개 변수 사용을 지원합니다.

$("td",$ (" #info_table")[0]).live("click",function(){/*추가 정보 표시*/}) 이러한 방식으로 "수탁자"는 기본 $(document)에서 $( " #infotable")[0], 버블링 여행을 저장합니다. 그러나 .live()와 함께 사용되는 컨텍스트 매개변수는 별도의 DOM 요소여야 하므로 여기서는 배열 인덱스 연산자를 사용하여 얻은 $("#infotable")[0]을 사용하여 컨텍스트 객체를 지정합니다.

.delegate()
앞서 언급했듯이 단일 .bind() 메서드의 한계를 극복하고 이벤트 위임을 구현하기 위해 jQuery 1.3에서는 .live() 메서드를 도입했습니다. 나중에 너무 긴 "이벤트 전파 체인" 문제를 해결하기 위해 jQuery 1.4에서는 .live() 메서드에 대한 컨텍스트 개체 지정을 지원했습니다. 불필요한 요소 컬렉션 생성 문제를 해결하기 위해 jQuery 1.4.2에서는 단순히 새로운 method.delegate()를 도입했습니다.

.delegate()를 사용하면 이전 예제를 다음과 같이 작성할 수 있습니다.

$("#info_table").delegate("td","click",function(){/ *추가 정보 표시*/})
.delegate()를 사용하면 다음과 같은 장점이 있습니다(또는 .live() 메서드의 다음 문제를 해결합니다).

대상 요소 선택기를 직접 설정합니다(" td" ), 이벤트("클릭") 및 핸들러는 "dragee" $("#info_table")에 바인딩되어 있으며 추가 요소가 수집되지 않으며 이벤트 전파 경로가 단축되고 의미가 명확합니다.
지원 지속적인 DOM 탐색 방법 이후 호출은 $("table").find("#info").delegate...를 지원하며 이는 정밀한 제어를 지원합니다.
.delegate() 방법이 비교적 완벽하다는 것을 알 수 있습니다. 해결책. 그러나 DOM 구조가 간단한 경우에는 .live()도 사용할 수 있습니다.

팁: 이벤트 위임을 사용할 때 대상 요소에 등록된 다른 이벤트 핸들러가 이벤트 전파를 방지하기 위해 .stopPropagation()을 사용하면 이벤트 위임이 유효하지 않게 됩니다.

결론
다음 상황에서는 .bind() 대신 .live() 또는 .delegate()를 사용해야 합니다.

은 DOM 바인딩에 있습니다. 동일한 이벤트를 여러 요소에 적용합니다.
DOM에 아직 존재하지 않는 요소에 이벤트를 바인딩합니다.
PS:

jQuery 1.7 Beta 1 릴리스 노트에 따르면 .bind(), .live() 및 .delegate()의 공존으로 인해 발생하는 불일치 문제를 해결하기 위해 jQuery 1.7에서는 새로운 이벤트 메소드인 .on() 및 .off()를 추가합니다: $(elems).on(events, selector, data, fn);
$(elems).off(events, selector, fn) );
selector를 지정하면 이벤트 위임이고, 그렇지 않으면 일반 바인딩입니다. 이전 API와 새 API 간의 대응은 다음과 같습니다.

jQuery code optimization event delegation_jquery

(참고: 이 글은 "JQuery Basics Tutorial (3rd Edition)"의 관련 장을 바탕으로 작성되었으며

도 참조합니다.

  • jQuery의 .bind(), .live(), .delegate()의 차이점
  • bind() vs live() vs Delegate() 함수
  • jQuery API)
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template