Ive had a problem that I cant fix while creating an image carousel in javascript. I am using jcarousel with a few "hacky" modifications to allow images with different widths (portrait/landscape) the end result is I am using some code that looks like this
function mycarousel_itemAddCallback(carousel, first, last, dir)
{
var thumbdir = 'gallery/' + dir + '/thumbs/' //set the thumbs dir
var fulldir = 'gallery/' + dir + '/full/' //set the full images dir
for (i 开发者_如何学Python= 0; i < 21; i++) {
var no = i+1; //number image we are on
var img = new Image(); //make a new image
img.src = thumbdir + no + '.jpg'; //set its source
var fullimg = fulldir + no + '.jpg'; //set full omages source as well
var html = mycarousel_getItemHTML(img.src, fullimg, img.width); //make some html for the image, with width
carousel.add(i+1, html, img.width); //add the image to the carousel, with width passed in
tagID = 'jcarousel-item-' + no; //get the css tag of the image just added
changeStyle(tagID, img.width); // force its height in inline css to prevent bugs
}
Now essentially, the problem seems to be that "img.width" ends up being 0 because the image has not yet loaded. this means all the images in the gallery end up having a width of 0 and are therefore not visible. refresh the page (so all the images are in the cache already) and everything works fine again, with "img.width" the correct value.
forcing a pause after setting the image to load with an alert allows img.width to become the right value, but obviously that's a horrible workaround. can anyone suggest a way of allowing the javascript to load the image, and get its size right, before continuing the script?
thanks in advance for all help
Use the onload
event like this:
var img = new Image();
img.onload = function(){
// image has been loaded
};
// proper way to assign any src right now
img.src = 'path there';
alert(img.width);
You need to use closures to pass variables into functions:
function foo(x,y)
{
//do stuff
}
for( var i = 0 ; i < 9 ; i++ )
{
var img = new Image();
img.onload = (function(a,b){ return function(){ foo(a,b) }; })(i,someVar);
img.src = "bar.jpg";
}
The nested functions work as follows: The outer function is in round brackets because we declare then call it in one go, so the (i,someVar) get passed in as (a,b) to the function. This function in turn returns a Pointer to a new second function that accepts no parameters. Wihtin this second function is one line of code, that calls foo, with (a,b) which, at the time of invokation are set to the current value of i and someVar. When foo eventually actually gets called (by onload) it's x and y parameters are then i and someVar.
Nobody actually understands any of this, we just pretend we do :-)
You can wrap the freaky nested functions in other helper functions, to make it a little less freaky. See http://cyclomedia.co.uk/?Javascript_Function_Pointer_Functions for my take on this,
精彩评论