JS Event Delegate

Source: Internet
Author: User

With the complexity of DOM structure and the application of dynamic scripting technology such as AJAX, event delegation naturally surfaced. jquery provides the. bind (),. Live (), and. Delegate () Methods for binding and delegate events. On the basis of discussing the internal realization of these methods, this paper shows their advantages and disadvantages and application occasions.

Event delegate

Examples of event delegation abound in reality. For example, three colleagues are expected to receive a courier in Monday. For the Signature Express, there are two ways: one is three people at the door of the company and other courier, the second is entrusted to the front desk mm for sign. In reality, most of US use commissioned programs (the company will not tolerate so many employees standing at the door to wait for courier). The front desk mm received the courier, she will determine who the recipient, and then according to the recipient's request for sign, or even on behalf of payment. This solution also has an advantage, that is, even if the company's new employees (regardless of how much), the front desk mm will be sent to the new staff after The courier to verify and sign on behalf of.

We know that when the DOM dispatches events for each element in the page, the corresponding elements typically handle events during the event bubbling phase. In structures like body > div > A, if you click the A element, the click event Bubbles from a to the Div and body (that is, the Document object). Therefore, the Click event that occurs above a, div and body elements can also be handled. Event delegation can be implemented by using the mechanism of event propagation (this is bubbling). Specifically, the event delegate is the event object itself that does not handle the event, but instead delegates the processing task to its parent element or ancestor element, or even the root element (document).

. Bind ()

Suppose you have a multi-row, multi-column table, and we want the user to click on each cell to see more information related to the content (for example, through a cue bar). To do this, you can bind the click event for each cell:

$("info_table td").bind("click", function(){/*显示更多信息*/});

The problem is that if there are 10 columns and 500 rows in the table to tie the order event, then finding and traversing 5,000 cells will cause the script to perform significantly slower, while saving 5,000 TD elements and corresponding event handlers will also consume a lot of memory (similar to having everyone standing at the door in person).

On the basis of the previous example, if we want to implement a simple photo album app that shows only 50 photos of thumbnails (50 cells) per page, the user clicks on the "page X" (or "next") Link to dynamically load another 50 photos from the server via Ajax. In this case, it seems that using the. bind () method for 50 cell binding events can be accepted.

It's not true. Using the. bind () method only binds the 50 cells in the first page to the Click event, and the cells in subsequent pages that are dynamically loaded will not have this clicked event. In other words,. bind () can only give an element binding event that is already present when it is called, and cannot bind events to future new elements (similar to a new employee receiving a courier).

Event delegation resolves both of these issues. specifically to the code, just use the new. Live () method in jquery 1.3 instead of the. bind () Method:

$("#info_table td").live("click",function(){/*显示更多信息*/});

Here the. Live () method binds the Click event to the $ (document) object (but this is not reflected in the code, which is also the. Live () method is a major cause of criticism, discussed in more detail later), and only need to give $ (document) Bind once (not 50 times, not 5,000 times) and then be able to handle the click events of subsequent dynamically loaded photo cells. When any event is received, the $ (document) object checks the event type and the event target, and if it is the click event and the event target is TD, then the handler entrusted to it is executed.

. Live ()

So far, everything seems to be perfect. Unfortunately, that is not the case. Because the. Live () method is not perfect, it has several major drawbacks:

    • The $ () function finds all TD elements in the current page and creates a jquery object, but does not use the TD element collection when confirming the event target. Instead of using a selector expression to compare with event.target or its ancestors, generating this jquery object creates unnecessary overhead;
    • By default the event is bound to the $ (document) element, and if the DOM nesting structure is deep, event bubbling through a large number of ancestor elements can result in performance loss;
    • It can only be placed behind a directly selected element and cannot be used after the DOM traversal method of concatenating, which is $ ("#info_table TD"). Live ... Yes, but $ ("#info_table"). Find ("TD"). Live ... No
    • Collect TD elements and create jquery objects, but the actual operation is a $ (document) object, puzzling.
The way to solve

To avoid generating unnecessary jquery objects, you can use a hack called "Early Delegates", which is called outside the $ (document). Ready () method. Live ():

(function($){ $("#info_table td").live("click",function(){/*显示更多信息*/});})(jQuery);

Here, (function ($) {...}) (JQuery) is an "immediate anonymous function"that forms a closure that prevents naming conflicts. Inside the anonymous function, the $ parameter references the jquery object. This anonymous function will not wait until the DOM is ready to execute. Note that when using this hack, the script must be linked and/or executed in the head element of the page. This timing is chosen because the document element is available, and the entire DOM is far from being generated; If you put the script in front of the end body tag, it makes no sense, because the DOM is fully available at that time.

To avoid the performance penalty caused by event bubbling, jquery supports the use of a context parameter when using the. Live () method, starting with 1.4.

$("td",$("#info_table")[0]).live("click",function(){/*显示更多信息*/});

In this way, the "trustee" is changed from the default $ (document) to $ ("#info_table") [0], saving the bubbling journey. However, the context parameter used in conjunction with. Live () must be a separate DOM element, so the context object is specified here using $ ("#info_table") [0], even if a DOM element is obtained using the array's index operator.

. Delegate ()

As mentioned earlier, in order to break the limits of the single. Bind () method, implement event delegation, JQuery 1.3 introduces the. Live () method. Later, to solve the problem of "event propagation chain" too long, jQuery 1.4 also supported specifying the context object for the. Live () method. To solve the problem of generating a set of unnecessary elements, JQuery 1.4.2 simply introduces a new method. Delegate ().

Using the. Delegate (), the preceding example can be written like this:

$("#info_table").delegate("td","click",function(){/*显示更多信息*/});

Using. Delegate () has the following advantages (or solves the following problem with the. Live () method):

    • Directly binds the target element selector ("TD"), the event ("click") and the handler to the "dragged-side" $ ("#info_table"), without additional collection elements, shortened event propagation paths, and explicit semantics;
    • Support is called after the DOM traversal method of concatenating, which is the support for $ ("table"). Find ("#info"). Delegate ..., supports precise control;

Visible, the. Delegate () method is a relatively perfect solution. However, in the case of a simple DOM structure, you can also use. Live ().

Tip: When you use event delegation, event delegation is invalidated if you use. Stoppropagation () To prevent event propagation if other event handlers are registered to the target element.

Conclusion

You should use. Live () or. Delegate () instead of. Bind () in the following cases:

    • Binds the same event to many elements in the DOM;
    • Binds an event to an element that does not already exist in the DOM;

PS: According to the release notes of the jquery 1.7 Beta 1, jquery 1.7 will add a new pair of event methods to solve the inconsistency problem caused by the coexistence of. Bind (),. Live (), and. Delegate (). On () and. Off ():
$ (Elems). On (events, selector, data, FN);
$ (elems). Off (events, selector, FN);
If selector is specified, the event is delegated; otherwise, it is a regular binding. The old and new APIs correspond to the following:

Transferred from: http://www.ituring.com.cn/article/467

JS Event Delegate

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.