views:

9

answers:

1

Hi there

I have a function

function preloadImage() {
varLink=".... link to my picture..."
$("#picture").attr("src", varLink).one("load", function() {
 // This is called after the image is loaded
 }}

Now I call this function many times in my jquery script. But I need it to call different functions after the image is loaded. Is there any more elegant way to do that instead of sending parametrs to function like:

function preloadImage(action)

and making several if then statements after the function is executed to replace the: // This is called after the image is loaded in my code?

So I basically need to do several things after image is loaded (callback) so I have to call this function with several different parameters or is there any other way?

Thank you

Jerry

A: 

You could pass the function itself in, for example:

function preloadImage(callback) {
  varLink=".... link to my picture..."
  $("#picture").one("load", callback).attr("src", varLink);
}

Then you can call it passing the function, for example

function doSomething() {
  alert("I'm loaded!, my src is: " + this.src);
}
preloadImage(doSomething);

You may want to pass the image link as well, I'm unclear from your example, but it seems likely you would want to, here's an example of that, with an anonymous function:

//define it
function preloadImage(imageUrl, callback) {
  $("#picture").one("load", callback).attr("src", imageUrl);
}

//example call
preloadImage('myImage.jpg', function () { 
  alert("I'm loaded!, my src is: " + this.src);
});

One last thing to keep in mind, you should bind the load event handler before setting the src, to make sure it fires in all cases (from cache for example), just like I have above.


Edit, adding version for comments:

function preloadImage(callback) {
  varLink=".... link to my picture..."
  $("#picture").one("load", function() {
    callback.apply(this, arguments);
    $('#ajax-loader').hide();
  }).attr("src", varLink);
}

There's an alternative as well, keep it simple and bind the "every time" function separately, like this:

//this handler happens on all future loads
$("#picture").load(function() { $('#ajax-loader').hide(); });

//this handler runs just once for this load
function preloadImage(callback) {
  varLink=".... link to my picture..."
  $("#picture").one("load", callback).attr("src", varLink);
}
Nick Craver
Thank you for so fast answer. I am still learning jquery.As I have a little more complicated function than I wrote, is there a way I pass the whole callback function and this: $('#ajax-loader').hide(); would also be executed after load EVERY TIME.So sometimes I need just ajax loader to hide, sometimes I need to have something more in my callback function. Now in every doSomething function I'd need to have the ajax loader hide. Is it possible to pass a function and execute loader hide to the afterload callback?
Jerry2
Thanx, the picture is the same all the time, I am trying to make a resize / crop picture application. I have to reload same picture as the src is a classic ASP call that handles the picture and writes it to stream. But it is good to know how to extend the picture anyway.
Jerry2
@Jerry2 - You're saying you want to say do something specific, *always* followed by that `$("#ajax-loader").hide();`? e.g. it should run after the callback *every* time?
Nick Craver
@Jerry2 - I added to the end of the answer what I think you're after, give it a try :)
Nick Craver
I have not tested yet but yes, I think you got what I wanted. I learned something new, that is the apply in jquery. Thank you very much for all your help.
Jerry2
@Jerry2 - Welcome, note I just added an alternative simpler approach as well, just a different way of going about the problem :)
Nick Craver
I get callback.apply is not a function in firebug now. Is it possible to call the preloadImage() without arguments? Because sometimes I call it without argumens, sometimes I use another function as argument.
Jerry2
@Jerry2 - Yup, just change `callback.apply(...)` to `if(callback) callback.apply(...)`
Nick Craver
I am now trying to use your simpler version with: $("#picture").one("load", callback).attr("src", varLink); Seem to get error when callback is not defined here. As I don't use callback.apply and more I am unable to fix this. I am a little lost in the brackets ;-))) From your answers I seem not to have a clue what is the difference between "bind" and "one". First I binded the load function and the callbacked get called one more time every time and I changed to "one" and it worked.
Jerry2
To use your simpler version is it possible to set callback to emptry string if it is not present so the $("#slika").one("load", callback).attr("src", varLink); would work even without passing function?
Jerry2
@Jerry2 you can replace callback with a dummy call for the sake of brevity, to do that you'd change `callback` to `callback || function(){}`, or check if callback is null with `if(callback) `$("#picture").one('load', callback); $("#picture").attr('src', varLink)` For the one vs bind difference, one only runs the handler once then removes it, bind leaves the handler to run every time the event fires.
Nick Craver
The dummy call works great without errors thank you again. I have a lot to learn still... Seems that if bind is inside a function that I call it recursevely add6 callback responses so I get one more each time. Inside a function it seems I have to use one ;-)
Jerry2
@Jerry2 - that's correct, the `.load()` was meant to be external to the function, in `document.ready` once, sorry for not making that clear :)
Nick Craver
I hope my final question: What get's executed first? The $('#ajax-loader').hide(); that is in load function or the callback and loading in: if(callback) $("#slika").one("load", callback); $("#slika").attr("src", varLink);
Jerry2
I have load in function preloadImage and it is in document.ready. But I call load using one not bind and it works ok it seems.
Jerry2
@Jerry - The `.hide()` gets called first, event handlers execute in *the order they were bound*, and since that one stays bound, it's always first in line. However, the UI thread won't update until your're done with whatever synchronous operation you're doing anyway, so both happen simultaneously to the user.
Nick Craver
Ah that is why I have a problem... This hide function not only hides div as I stated for simplicity, it also clears the width and height of the picture (if it wasn't resized or cropped remove dimensions). Of course now the width and height is removed first in load function and the picture is loaded later and the dimensions are not removed. And you say it is no way to remove the order... I'll have to use your first solution I think then.
Jerry2