Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

jquery

I have multiple images on my page. To detect broken images , I used this found on SO.

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

This works fine on the first image which I understand. But when I change this to

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

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

like image 998
user1252966 Avatar asked Mar 22 '12 07:03

user1252966


People also ask

What is jQuery one method?

jQuery one() Method The one() method attaches one or more event handlers for the selected elements, and specifies a function to run when the event occurs. When using the one() method, the event handler function is only run ONCE for each element.

What is difference between on and bind in jQuery?

on() method is the preferred method for attaching event handlers to a document. For earlier versions, the . bind() method is used for attaching an event handler directly to elements. Handlers are attached to the currently selected elements in the jQuery object, so those elements must exist at the point the call to .

What is jQuery once?

The . once() function takes one or two parameters: if there's just one and if it's a string, it filters out all elements which already have the processing function with that label run. If there is a second parameter, it runs that function for each matched elements that has not yet been processed, similar to . each() .


2 Answers

Community wiki: This generic answer does not contribute to the question OP posted but relative to the title.

The concept of one() and on() can be explained with the below code.

one() function is automatically moved to off state after first instance of occurance.

on() is identical to one() but it needs to be manually put to off state otherwise the number of instances has no limit.

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>
like image 112
3 revs Avatar answered Oct 06 '22 00:10

3 revs


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

So, there must be something else going on in your code like maybe the image objects haven't been loaded into the DOM yet when you run this code or something like that.

If you were trying to use delegated event handling to do this (which your example does not show), then you may run into issues where the 'error' event doesn't propagate.

It may also be that your code has timing issues due to caching. Trying to install these types of error handlers on images that are already in the DOM is a race condition. You're trying to get the error handler installed before it gets called, but the image has already started loading and the event might have already fired before you get the event handler installed. Subsequent page loads (after the first) may have cached other page elements or DNS references so it may get to the error handler quicker and perhaps even before your JS can run and install the error handlers.

I know this is an issue with browser caching and the onload event. You can only reliably get the onload event if you attach the event handler either in the embedded HTML (so it's there when the <img> tag is first parsed or if you attach it before the .src property has been set (if creating the image programmatically). That would suggest that you can't reliably set error handlers the way you are doing for images that are in the page HTML.

My suggestion would be this:

  • Don't try to install error handlers like this after the images are in the DOM.
  • If you assign them on programmatically generating images, then assign the event handlers before .src is assigned.
  • If you need these on images in the page's HTML, then you will have to put the event handlers in the HTML with something like <img src="xxx" onerror="yourErrorFunc(this)"> because that's the only way to guarantee that the handlers are installed before the event can occur.
like image 29
jfriend00 Avatar answered Oct 06 '22 01:10

jfriend00