JQuery event bindings and delegate instances

  • 2020-03-30 04:23:11
  • OfStack

This article illustrates jQuery event bindings and delegates. Share with you for your reference. Specific methods are as follows:

Binding and delegating jQuery events can be done in a number of ways, on()  , the bind ()   , the live ()   Delegate (), and one().
 
Sometimes we might bind an event like this:

$("#div1").click(function() {  
    alert(" Click to trigger "); 
});

The above event binding can be implemented in a variety of ways:
 
1. On ()

//No data parameter & NBSP; < br / >
$("p").on("click", function(){  
alert( $(this).text() ); 
}); 
 
//There are data parameters & NBSP; < br / > function myHandler(event) { 
alert(event.data.foo); 

$("p").on("click", {foo: "bar"}, myHandler)

Corresponding to on() is off(), which is used to remove the event binding:

var foo = function () {  
  // code to handle some kind of event 
}; 
// ... now foo will be called when paragraphs are clicked ... 
$("body").on("click", "p", foo); 
 
// ... foo will no longer be called. 
$("body").off("click", "p", foo);

Off () : removes the binding for on()
One () : bind only once.
 
2. The bind ()

Parameters:
(type, [data], function (eventObject))
Type: a string containing one or more event types separated by Spaces. For example, "click" or "submit" can also be a custom event name.
Data: additional data object passed to the event object as the value of the event.data attribute
 
Fn: the handler bound to the event above each matched element
 
(type, [data], false)
Type: a string containing one or more event types separated by Spaces. For example, "click" or "submit" can also be a custom event name.
Data: additional data object passed to the event object as the value of the event.data attribute
 
False: setting the third parameter to false invalidates the default action.
 
Bind multiple event types simultaneously:

$('#foo').bind('mouseenter mouseleave', function() {  
  $(this).toggleClass('entered'); 
});

Bind multiple event types/handlers simultaneously:

$("button").bind({  
  click:function(){$("p").slideToggle();}, 
  mouseover:function(){$("body").css("background-color","red");},   
  mouseout:function(){$("body").css("background-color","#FFFFFF");}   
});

You can pass some additional data before the event is processed.

function handler(event) {  
  alert(event.data.foo); 

$("p").bind("click", {foo: "bar"}, handler)


Cancel the default behavior and prevent event bubbling by returning false.

$("form").bind("submit", function() { return false; })

Problems with bind

If there are 10 columns of 500 rows in the table to bind the click event, then finding and traversing 5,000 cells will cause the script to execute significantly slower, and saving 5,000 td elements and the corresponding event handler will also take up a lot of memory (similar to having everyone stand at the door and wait for the express).

Building on the previous example, if we want to implement a simple photo album application that only displays thumbnails of 50 photos (50 cells) per page, the user can click the "page x" (or "next page") link to dynamically load another 50 photos from the server through Ajax. In this case, it seems acceptable to use the.bind() method to bind events for 50 cells.

Not so. Using the.bind() method binds click events to only 50 cells on the first page, and none of the cells on the dynamically loaded subsequent pages will have this click event. In other words,.bind() can only bind events to elements that were already there when it was called, not events to new elements that will be added in the future (similar to a new employee who can't get express).

Event delegates can solve both problems. To be specific, just replace the.bind() method with jQuery 1.3's new.live() method:

$("#info_table td").live("click",function(){});

Here. The live () method will reduce the click event is bound to the $(document) objects (but that reflect not to come out from the code, it is. The live () method is one major reason for the much-maligned, discussed in more detail later), and only need to give the $(document) binding once (not 50 times, more than 5000 times), then I can handle the click event of the follow-up dynamic loading photo cell. When any event is received, the $(document) object checks the event type and the event target, and if it is a click event and the event target is td, then the handler delegated to it is executed.
 
Unbind () : removes the binding performed by bind.
 
3. The live ()

So far, so good. Unfortunately, this is not the case. Because the.live() method is not perfect, it has the following major disadvantages:
The $() function finds all the td elements in the current page and creates a jQuery object, but instead of using this set of td elements to identify the event target, it USES a selector expression to compare it to the event.target or its ancestor elements, so generating this jQuery object causes unnecessary overhead.
By default, the event is bound to the $(document) element. If the DOM is deeply nested, the event bubbles through a large number of ancestor elements, resulting in a performance loss.
It can only be placed after directly selected elements, and cannot be used after contiguous DOM traversal methods, i.e. $("#info_table td").live... Yes, but $("#info_table").find("td").live... No;
Collecting td elements and creating jQuery objects, but actually working with a $(document) object, is confusing.
The solution
To avoid generating unnecessary jQuery objects, you can use a hack called "early delegate," which is called outside the $(document).ready() method.

(function($){  
    $("#info_table td").live("click",function(){}); 
})(jQuery);

Here, (function ($) {... })(jQuery) is an "immediately executed anonymous function" that forms a closure to prevent name collisions. Inside the anonymous function, the $parameter references the jQuery object. This anonymous function does 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. The timing was chosen because the document element was available and the entire DOM was far from being generated. It makes no sense to put the script before the closing body tag, because the DOM is fully available by then.

In this way, the "trustee" changes from the default $(document) to $("#info_table")[0], saving bubbling trips. However, the context parameter used with.live() must be a separate DOM element, so the context object is specified using $("#info_table")[0], which is a DOM element obtained using the index operator of the array.  
 
4. The delegate ()

Using.delegate() has the following advantages (or solves the following problem with the.live() method) :
Directly bind the target element selector (" td"), the event (" click") and the handler to the "dragged-side" $("#info_table") without additional collection of elements, the event propagation path is shortened, and the semantics is clear.

So the.delegate() method is a relatively perfect solution. However, if the DOM structure is simple, you can also use.live().

Tip: when using an event delegate, if other event handlers registered on the target element use.stoppropagation () to prevent event propagation, the event delegate becomes invalid.
 
Undelegate (): removes the delegate's binding


Related articles: