Scope problem

Greetings!

I’ve been programming and came to this dead end.
The problem is, that the things added in the function don’t extend outside.
Even though I have defined the fadeimages array outside the for loop.

I’ve tried removing the “var”, defining it inside the function, defining it in the for loop, but it doesn’t seem to be working. I’ve got a hunch it may be a bigger problem in the design.


var fadeimagesPHP=new Array();
fadeimagesPHP[0]=["img/gal/blablabla.jpg"];
var fadeimages = new Array();
var imagePreload = new Array();

	for (var i = 0, len = fadeimagesPHP.length; i < len; i++) {
	imagePreload[i] = new Image(); 
	imagePreload[i].src = fadeimagesPHP[i];
	  
	  imagePreload[i].onload = function(){
	  fadeimages.push( this.src );
	  }  
	}

Found some info:
http://stackoverflow.com/questions/1451009/javascript-infamous-loop-problem

fadeimagesPHP[0] is an array, not a string url. You can’t assign an array to an src attribute.

You probably meant


var fadeimagesPHP = ["img/gal/blablabla.jpg"];

No,

That was an example of fadeimagesPHP, it was just the first position of the array, I didn’t feel the need to include other elements of the array. (fadeimagesPHP[1]=[“img/gal/blebleble.jpg”]; )

And that was not the problem, the problem has to with FADEIMAGES array.

I add the references to images (img/gal/*.jpg) in the onload or smth function.
And everything is fine when I call the alert method on FADEIMAGES inside the onload function, however when I call it outside of it, for example in the for loop or in global scope, the FADEIMAGES array seems to contain no elements.

I know you’re abbreviating code. If those sub arrays have multiple elements, this will surely cause a failure. You created a multidimensional array, and are trying to use the inner arrays as strings. You’re relying on those sub arrays to get turned into strings automatically for you, and it only has a chance of working if the sub array has a single element. It might not work well cross browser. It’s plain wrong.


//fadeimagesPHP[0]=["img/gal/blablabla.jpg"];
fadeimagesPHP[0] = "img/gal/blablabla.jpg";

The fadeimages array will only get elements put into it if the image fires the onload event. If there’s an error, you get no onload.

You also have a race condition. You assign a value to the src attribute before you assign the load event handler. If the image is locally cached, it may finish loading before you attach the event handler. So, attach the event handler first, then assign the string to the src attribute.

Fix those issues, and if you still have problems, post a small but completely running sample of the code. Link to external images with absolute urls for us.

?

I’m not following your aid.
I am a newcomer, as you could problably assume.

I come from java language,
Could you please elaborate, I don’t understand the array logic?
Multidimensional array? Where?

I define an array

var fadeimagesPHP=new Array();

I add an string in position 0

fadeimagesPHP[0]=["img/gal/blablabla.jpg"];

Like in Java, however you must define the length of the array.
Multidimensional would be with 2 positions or more?

like java, javascript has an array literal syntax.

In java terms, you have something kinda like this


ArrayList fadeimagesPHP = new ArrayList();
String[] tmp = {"img/gal/blablabla.jpg"};
fadeimagesPHP.add(0, tmp);


// array literals
var array = [1, 2, 3];
var array = [1];

You really don’t need to do new Array() in javascript, just use the literal syntax.


var fadeimagesPHP = ["1.jpg", "2.jpg"];

The reason it may have been working is because, like java, the toString() method was being called, which presents the values as a string, comma delimited. So, if the array had only a single element, then it wouldn’t be obvious that it wasn’t really a string.


	for (var i = 0, len = fadeimagesPHP.length; i < len; i++) {
	    alert(fadeimagesPHP[i] instanceof Array); //true

	}

:confused:

From wikipedia:
http://en.wikipedia.org/wiki/JavaScript_syntax#Array

Declaration of an array


myArray = [0,1,,,4,5];            // array with length 6 and 6 elements, including 2 undefined elements
myArray = new Array(0,1,2,3,4,5); // array with length 6 and 6 elements
myArray = new Array(365);         // an empty array with length 365

Accessing elements of an array


myArray[1];  //this gives you the 2nd item in myArray
myArray["1"];

There is no multidimensionality found here.
The code gets generated with PHP dynamically,
so the array could not be constructed with Array literal.

…and I think the problem may be something to do with closures:
http://joust.kano.net/weblog/archive/2005/08/08/a-huge-gotcha-with-javascript-closures/

Yes there is. You just posted an example of the array literal syntax. What do you think [“img/gal/blablabla.jpg”] is? An array with a single string element. What did you assign it to? An element in another array.

Yes it can, quite easily, not that it really makes a difference though.

Sorry, I’m not getting it.

I posted the PHP here:
http://www.sitepoint.com/forums/showthread.php?p=4568653#post4568653

How would you do it otherwise?


// Create an array 
var fadeimagesPHP=new Array();
// assign "img/gal/blablabla.jpg" to the first position of array
fadeimagesPHP[0]=["img/gal/blablabla.jpg"];

Why isn’t it an Array with a single string element?
Where exactly do I go wrong?

Take some time to try to digest what I’ve said in this thread. I’ve given the answer multiple times.

There is no problem related to closures in the code you posted. Obviously though, that isn’t all of your code.

I removed the from the array assignments, I guess that was the thing you were hinting at? If so then we wasted 9 posts for it.

But it still isn’t working, I changed the order of the assignment, of src, as you suggested.

HTML version:
http://web.zone.ee/testcss/indexs.html

as you can see I alert the fadeshow from inside and outside of the function.
But what is weird, to me, that the alert from outside the loop gets called first.
So I think the fadeimages may be empty at the time of outside alert execution

It’s working perfectly now(fully populating the fadeimages array) .

Your problem is you are not waiting for the images to load before reading the fadeimages array. And, it’s most likely going to be empty, or only partially filled, if you don’t wait long enough. The browser loads the images asynchronously, so your for loop completes very quickly before any images are likely to have fully loaded. So, you would want to use events to help you wait long enough.

But, what are you trying to do? Start a slideshow only after the images have preloaded? Are you trying to only pass images that successfully loaded to the slideshow?

Well,
the idea was that the slideshow would play only the images that are fully loaded, no half loaded images are shown.

1. slideshow starts
2. slideshow loads the fadeimages
3.(may start even as first, doesn’t matter) the onload function continues to add filenames to the fadeimages array until all are loaded.

Slideshow starts no matter how many images are loaded, but gets the updated image (fadeshow array) data.

But it is getting clear to me that it may need something like multitasking, nonlinear execution. Or maybe I could use some time functions to check the fadeimages array for every once in a while.

Ya, your fade.js script certainly isn’t going to work for that, the way it’s currently coded.

If you look around, you might find an existing slideshow that has some sort of slideshow.addImage() interface, which is designed to behave properly.

I don’t know if you want your slideshow to automatically loop when it reaches the end, if so, it’s needs a way to know what the end is. Because when it hits the end of the images array, it needs to decide if it should start over from the beginning, or if it should just wait for another image to get added. So maybe let it be aware of how many it will eventually get, or make a setAutoLoopBehavior() method so you can turn the feature on when you’re done adding images.

Hmmm,
that’s a pretty old slideshow I quess.
The images should loop.
I’ve actually searched for more modern ones,
however anything decent is yet to come up.

Anyways, thanks for your time.:slight_smile:

Generally speaking, you’ll find better slideshows/sliders etc… when they depend on one of the major javascript libraries, like jquery or prototype. The code is typically better written, more robust, and more cross browser than most of that old junk still floating across the intertubes from 5-10 years ago.

You can try searching for jquery slideshow, or jquery slider and probably find something nicer in short time. Here’s one http://www.sitepoint.com/forums/showthread.php?t=666699