📜 ⬆️ ⬇️

Using Delegate and Undelegate in jQuery 1.4.2

jQuery
In the comments to the announcement of version 1.4.2 there were many questions about the 2 new methods that appeared in the new version of jQuery
You've probably heard that 2 new methods were added to jQuery 1.4.2: .delegate () and .undelegete (). These two methods are designed for the same purposes as the .live () and .die () methods, they only use a different syntax.

For newbies: .live () is a method in jQuery that allows you to bind an event to an element in a document, just as easy as an element that appears in the future. For example, you bind an event via .live ():
$( 'img.photo' ).live( 'click' , function (){
lightboxify( this );
});

Then add some photos via AJAX:
// append an image
$( 'body' ).append( '<img src="face.jpg" alt="silly face" class="photo"/>' );


The click () event is attached to a new image. There is no need for a new event binding. Conveniently?

Not so long ago, there were several discussions about the .live () method ( note translating links to the jQuery forum and paulirish.com). One of the problems discussed was that the .live () method gave an error if you tried to use it in the chain of calls (alongside traversals). For example:
// FAILS
$( 'ul' ).find( 'li' ).next().live( 'click' , function (){});
// FAILS
$( 'ul' ).parent().nextAll().live( 'click' , function (){});


And even when binding to a regular DOM element, errors occur:
// FAILS
$( document .body).live( 'click' , function (){});

Unfortunately, if you want to use .live (), it must be on the top of the chain:
// WORKS
$( 'ul li' ).live( 'click' , function (){})

Since this can be confusing for many people using traversing and the call chains provided by jQuery, this has resulted in a discussion of the syntax of the .live () method. Why, looking like other methods, does it behave differently? Later, this was reflected in the drastic rework of the code, the developers decided to introduce .delegate () and .undelegate () to complement .live () and .die ().
Here is an example of how .live () and .die () are commonly used and how you can now use .delegate () and .undelegate ():
Old method:
// Using .live()
$( "table" ).each( function (){
$( "td" , this ).live( "hover" , function (){
$( this ).toggleClass( "hover" );
});
});
// Using .die()
$( "table" ).each( function (){
$( "td" , this ).die( "hover" );
});

New method:
// Using .delegate()
$( "table" ). delegate ( "td" , "hover" , function (){
$( this ).toggleClass( "hover" );
});

// Using .undelegate()
$( "table" ).undelegate( "td" , "hover" );


The advantage of the .delegate () method is that it allows you to define the context. This ensures that we do not need to go through the entire DOM structure to reach the desired element. The .live () method goes all the way through the DOM structure each time, unless you define the context like this:
$( 'td' , $( 'table' )[0]).live( 'hover' , function (){})

It looks awful!
Some people think delegate () is similar to the bind () method. As you will see below, the syntax is slightly different.
// .bind() way
$( 'ul li' ).bind( 'click' , function (e){
// Do something with bind
});

// .delegate() way
$( 'ul' ). delegate ( 'li' , 'click' , function (e){
// Do something with delegate
});

In short, the difference between .bind () and .delegate () is that .bind () only adds an event to an item on the page. .delegate () keeps track of the appearance of new elements and adds an event to them when they turn around.
')

.Delegate () method bugs


.delegate () does not allow, unlike .bind (), to handle an array of events ( object map of events ). Example with .bind ():
// This works wonderfully
$( 'ul li' ).bind({
click: function (e){
// Something on click
},
mouseover: function (e){
// Something on mouse over
}
});

An error occurs when we try to do the following:
// FAILS!
$( 'ul' ). delegate ( 'li' , {
click: function (e){
// Something on click
},
mouseover: function (e){
// Something on mouse over
}
});

I am not sure of the reasons for this, but I think I’m not the only one who is thinking about it.
By the way, .bind () did not have this feature until jQuer 1.4. If you decide to use the same method in .live () and .delegate (), Robert Katits wrote a small piece of code that you can include in yours. Take it here .
I recommend using the Robert Katits patch above, although there are, of course, other methods. For example, you can build your own custom object map:
var customObjMap = {
click : function (e){
// Something on click
},
mouseover : function (e){
// Something on mouse over
}
};

$( 'ol' ). delegate ( 'li' , 'click mouseover' , function (e){
if ($.isFunction(customObjMap[e.type])){
customObjMap[e.type].call( this , e);
}
});

* This source code was highlighted with Source Code Highlighter .


The other bug of both .delegate () and .live () methods is that when you add a mouseenter and mouseleave event to an element, and then check its type (e.type) in the callback function, it is incorrectly displayed as mouseover and mouseout. .bind () on the other hand, as expected, shows mouseenter and mouseleave. Here is an example:
$( 'ol' ). delegate ( 'li' , 'mouseenter' , function (e){
alert(e.type); // outputs mouseover
});
$( 'ol li' ).bind( 'mouseenter' , function (e){
alert(e.type); // outputs mouseenter
});

UPDATE: This bug is fixed and in new jQuery versions everything will be OK.

In general, bugs do not diminish the advantages that the .delegate () and .undelegte () methods provide. A good addition to the jQuery core.

Source: https://habr.com/ru/post/86604/


All Articles