SitePoint Sponsor

User Tag List

Results 1 to 16 of 16

Thread: Scope problem

  1. #1
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    99
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    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.

    Code:
    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/1...s-loop-problem

  2. #2
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    fadeimagesPHP[0] is an array, not a string url. You can't assign an array to an src attribute.

    You probably meant
    Code:
    var fadeimagesPHP = ["img/gal/blablabla.jpg"];

  3. #3
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    99
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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.

  4. #4
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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.
    Code:
    //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.

  5. #5
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    99
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ?

    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
    Code:
    var fadeimagesPHP=new Array();
    I add an string in position 0
    Code:
    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?

  6. #6
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    like java, javascript has an array literal syntax.

    In java terms, you have something kinda like this

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

    Code:
    // 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.
    Code:
    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.

    Code:
    	for (var i = 0, len = fadeimagesPHP.length; i < len; i++) {
    	    alert(fadeimagesPHP[i] instanceof Array); //true
    
    	}
    Last edited by crmalibu; Apr 20, 2010 at 10:45. Reason: corrected my rusty java example

  7. #7
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    99
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)


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

    Declaration of an array
    Code:
    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
    Code:
    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...ript-closures/

  8. #8
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Koora View Post
    There is no multidimensionality found here.
    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.


    Quote Originally Posted by Koora View Post
    The code gets generated with PHP dynamically,
    so the array could not be constructed with Array literal.
    Yes it can, quite easily, not that it really makes a difference though.

  9. #9
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    99
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry, I'm not getting it.

    I posted the PHP here:
    http://www.sitepoint.com/forums/show...53#post4568653

    How would you do it otherwise?

    Code:
    // 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?

  10. #10
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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.

  11. #11
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    99
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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

  12. #12
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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?

  13. #13
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    99
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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.

  14. #14
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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.

  15. #15
    SitePoint Enthusiast
    Join Date
    Feb 2010
    Posts
    99
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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.

  16. #16
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •