Difference between jQuery.one () and jQuery.on ()

I have several images on my page. To detect broken images, I used this in SO.

$('.imgRot').one('error',function(){ $(this).attr('src','broken.png'); }); 

This works fine in the first image that I understand. But when I change it to

 $('.imgRot').on('error',function(){ $(this).attr('src','broken.png'); }); 

it does not work on any of the images. Can someone tell me why?

+6
source share
3 answers

Community wiki: This general answer does not affect the OP question, but regarding the name.

The concepts of one () and on () can be explained using the code below.

Function

one() automatically goes into state after the first instance of the event.

on() is identical to the one () parameter, but it must be disabled manually, otherwise the number of instances will not be limited.

 var i = 1; $('.one').one('click', function() { $(this).text('I am clickable only once: ' + i); i++; }); var j = 1; $('.multiple').on('click', function() { $(this).text('I was clicked ' + j + ' times'); j++; }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="one">Click me</div> <div class="multiple">Click me</div> 
+10
source

If you look at the source code for .one() in jQuery 1.7, it just calls .on() inside, except that after the event occurs, it removes the event handler. Thus, in your case there should be no difference, because error is an event that should occur only once per object.

So, there should be something else in your code, for example, image objects are not yet loaded in the DOM when you run this code or something like that.

If you tried to use delegated event processing for this (which your example does not show), you may run into problems in which the "error" event does not propagate.

It is also possible that your code has synchronization problems due to caching. Trying to install these types of error handlers on images that are already in the DOM is a race condition. You are trying to install an error handler before it is called, but the image has already loaded, and the event may have already been fired before you get the installed event handler. Subsequent page loads (after the first one) may cache other page elements or DNS links, so they can access the error handler faster, and perhaps even before your JS can start and install the error handlers.

I know this is a problem with browser caching and onload . You can only reliably receive the onload if you attach the event handler in the embedded HTML (so that there when the <img> tag is parsed first, or if you attach it before the .src property was set (if creating the image programmatically). assumes that you cannot reliably set error handlers the way you do for images on an HTML page.

My suggestion would be as follows:

  • Do not try to install error handlers like this after the images are in the DOM.
  • If you assign them when programmatically creating images, assign event handlers before assigning .src .
  • If you need this in the images on the HTML page, you will have to put the event handlers in HTML with something like <img src="xxx" onerror="yourErrorFunc(this)"> , because this is the only way to guarantee that the handlers will be installed before the event happens.
+6
source

jQuery reuses the on method for one. The following is the jQuery internal code, where they will pass the hard-coded "1" value to the jQuery.on () function. They will disable the triggered event further for the element using jQuery.off ()

  on:function( types, selector, data, fn, one ) { if ( one === 1 ) { origFn = fn; fn = function( event ) { jQuery().off( event ); return origFn.apply( this, arguments ); }; } off:function(types, selector, data, fn){ on(types, selector, data, fn, 1); } 

So, in your case, the β€œerror” is the type of event that was triggered in the first image, and when the jQuery.one () method raised this event, it disconnected and then did not activate it for further use of the $ ('. ImgRot') elements

0
source

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


All Articles