Delegation of jQuery code optimization events

Source: Internet
Author: User

JQuery provides the. bind (),. live (), and. delegate () methods for binding and delegate events. Based on the internal implementation of these methods, this article demonstrates their advantages and disadvantages and their applicability.

Event Delegate

Event delegation examples are everywhere in reality. For example, three colleagues are expected to receive a courier on Monday. There are two ways to sign for express delivery: one is to wait for delivery by three people at the company's door, and the other is to entrust the front-end MM to sign for it. In reality, most of us adopt delegated solutions (the company will not tolerate so many employees standing at the door to wait for express delivery ). After receiving the express delivery, the front-end MM will determine who the recipient is, and then sign for the delivery according to the recipient's requirements, or even pay for the delivery. This solution also has an advantage, that is, even if the company has a new employee (no matter how many), the front-end MM will verify and sign for the new employee after receiving the courier.

We know that when DOM assigns an event to each element on the page, the corresponding elements generally process the event in the event bubble stage. In a structure such as body> div> a, if you click element a, the click event will bubble from a until div and body (that is, the document Object ). Therefore, when a click event occurs on a, the div and body elements can also be processed. Event delegation can be implemented by using the event propagation (bubble here) mechanism. Specifically, event delegation means that the event target does not process the event itself, but delegates the processing task to its parent element, ancestor element, or even root element (document ).

. Bind ()
Suppose there is a table with multiple rows and multiple columns. We want users to click each cell to see more information related to the content (for example, through the prompt bar ). Therefore, you can bind a click event to each cell:

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

The problem is that if the table contains 10 columns and 500 rows for which you want to bind a click event, searching and traversing 5000 cells will significantly slow the script execution, the storage of 5000 td elements and corresponding Event Handlers also occupy a large amount of memory (similar to letting everyone stand at the door and wait for the express delivery ).

Based on the previous example, if we want to implement a simple photo album application, each page will display only 50 thumbnail photos (50 cells ), you can click the "page x" (or "next page") link to dynamically load 50 more photos from the server using Ajax. In this case, it seems that the. bind () method is acceptable for binding events to 50 cells.

This is not true. By using the. bind () method, only 50 cells on the first page are bound with a click event. This click event is not found in the subsequent cells on the Dynamically Loaded page. In other words,. bind () can only bind events to existing elements when calling it, and cannot bind events to new elements in the future (similar to new employees cannot receive express deliveries ).

Event delegation can solve the above two problems. Specifically, you only need to replace the. bind () method with the. live () method added by jQuery 1.3:

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

Here. the live () method binds the click event to the $ (document) object, which is not reflected in the Code. the live () method is criticized for an important reason, which will be discussed in detail later), and you only need to bind $ (document) Once (not 50 times, not 5000 times ), then, you can process the click events of the subsequently Dynamically Loaded photo cells. When receiving any event, the $ (document) object checks the event type and event Target. If it is a click event and the event target is td, it executes the handler entrusted to it.

. Live ()
So far, everything seems perfect. Unfortunately, this is not the case. Because the. live () method is not perfect, it has the following main disadvantages:

Compile get or its ancestor element for comparison, so generating this jQuery object will cause unnecessary overhead;
By default, events are bound to the $ (document) element. If the DOM nested structure is deep, event bubbling causes performance loss through a large number of ancestor elements;
It can only be placed behind directly selected elements and cannot be used after the joined DOM Traversal method, that is, $ ("# infotable td "). live... yes, but $ ("# infotable "). find ("td "). live... no;
It is confusing to collect td elements and create jQuery objects, but actually operate on $ (document) objects.

Solution

To avoid generating unnecessary jQuery objects, you can use an hack called "Early delegate", that is, call. live () outside the $ (document). ready () method ():
Copy codeThe Code is as follows:
(Function ($ ){
$ ("# Info_table td"). live ("click", function () {/* show more information */});
}) (JQuery );

Here (function ($) {...}) (jQuery) is an "anonymous function executed immediately" that forms a closure to prevent name conflicts. Inside an anonymous function, the $ parameter references the jQuery object. This anonymous function will not be executed until the DOM is ready. Note: When using this hack, the script must be linked and/or executed in the head element of the page. The reason for choosing this time is that the document element is available at this time, and the entire DOM is far from being generated. It makes no sense to put the script in front of the ending body Tag, at that time, DOM was fully available.

To avoid the performance loss caused by event bubbling, jQuery supports using a context parameter when using the. live () method from 1.4:

$ ("Td", $ ("# info_table") [0]). live ("click", function () {/* show more information */}); in this way, the "recipient" starts from the default $ (document) changed to $ ("# infotable") [0], saving the bubble journey. However. the context parameter used by live () must be a separate DOM element. Therefore, $ ("# infotable") [0] is used to specify the context object. it is a DOM element obtained by using the index operator of the array.

. Delegate ()
As mentioned above, in order to break through the limitations of a single. bind () method and implement event delegation, jQuery 1.3 introduces the. live () method. Later, in order to solve the problem that the "event propagation chain" is too long, jQuery 1.4 also supports specifying context objects for the. live () method. To solve the problem of unnecessary element set generation, jQuery 1.4.2 directly introduces a new method. delegate ().

When using. delegate (), the preceding example can be written as follows:

$ ("# Info_table"). delegate ("td", "click", function () {/* show more information */});
The use of. delegate () has the following advantages (or solves the following problems of the. live () method ):

Bind the target element selector ("td"), event ("click"), and handler directly to the "dragged" $ ("# info_table, no additional elements are collected, the event Propagation Path is shortened, and the semantics is clear;
You can call the concatenation DOM Traversal method, that is, $ ("table"). find ("# info"). delegate... is supported, and precise control is supported;
The. delegate () method is a perfect solution. However, when the DOM structure is simple, you can also use. live ().

Tip: When you use event delegation, if other Event Handlers registered to the target element use. stopPropagation () to prevent event propagation, the event Delegate will become invalid.

Conclusion
In the following cases, use. live () or. delegate () instead of. bind ():

Bind the same event to many elements in the DOM;
Bind events to elements that do not exist in the DOM;

PS: According to the release instructions of jQuery 1.7 Beta 1, jQuery 1.7 aims to solve the problem. bind (),. live () and. if delegate () coexist, a new event method will be added :. on () and. off ():
$ (Elems). on (events, selector, data, fn );
$ (Elems). off (events, selector, fn );
If selector is specified, it is the event Delegate; otherwise, it is the regular binding. The new and old APIs correspond to the following:

(Note: This article is based on the content of the relevant chapter in jQuery basic tutorial (version 3rd ).

  • The Difference Between jQuery's. bind (),. live (), and. delegate ()
  • Bind () vs live () vs delegate () function
  • JQuery API)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.