SitePoint Sponsor

User Tag List

Results 1 to 5 of 5

Thread: array scope

  1. #1
    SitePoint Addict
    Join Date
    Oct 2009
    Location
    London, UK
    Posts
    382
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    Question array scope

    Hi there,

    I'm writing a simple image fader using jQuery. I create an array of images on $(document).ready, and then access it on $(window).load. Only the array appears empty. Is this something to do with the array's scope? (Presumably I wouldn't appear at all if this were the case?)

    Here's my code:
    Code:
    $(document).ready(function(){
    	$('#main_img').append('<div id="top_img"></div><div id="next_img"></div>');
    
    	var images = [];
    	$('#main_img img').each(function(){
    		var src = $(this).attr('src');
    		images.push(src);
    	}).remove();
    	$('#top_img').hide().css({backgroundImage:"url(" + images[0] + ")"});
    
    	$(window).load(function(){
    		console.log(images); //output: []
    		$('#top_img').fadeIn();
    		t = setTimeout(function(){cycle(images)}, delay);
    	});
    		
    	console.log(images); //output: ["/images/lazarus_glass_4f97eef5e60ca.jpeg", "/images/lazarus_glass_4f97ef5354142.jpeg"]
    }
    Any ideas how I can get the filled array within the $(window).load() block?

    Cheers,
    Mike

  2. #2
    SitePoint Wizard bronze trophy chris.upjohn's Avatar
    Join Date
    Apr 2010
    Location
    Melbourne, AU
    Posts
    2,192
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    The reason why it would be logged as an empty array is because the load function for the window gets executed first, I'm trying to understand why your using $(window).load() as it's never going to work correct within a $(document).ready() method.

  3. #3
    SitePoint Addict
    Join Date
    Oct 2009
    Location
    London, UK
    Posts
    382
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Ahh, yeah ok that would explain it. Well the reason being is because I want to hide the $('#top_img') on $(document).ready, then fadeIn once all the images are loaded. Could you suggest a better way of doing this?

    Cheers,
    Mike

  4. #4
    SitePoint Wizard bronze trophy chris.upjohn's Avatar
    Join Date
    Apr 2010
    Location
    Melbourne, AU
    Posts
    2,192
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    See how the below goes for you, i rewrote your code so now jQuery will assign a load event to each image allowing for an accurate load count.

    Code JavaScript:
    $(function() {
        $('#main_img').append('<div id="top_img"></div><div id="next_img"></div>');
     
        // Preload the images
        var images = [],
            total  = 0;
     
        $('img', '#main_img').each(function() {
            // Increment the total number of images
            total++;
     
            // Push the image into the images array
            images.push(this.src);
     
            // Set an event handler to the image
            $(this).load(function() {
                total--;
     
                // If all the images have loaded start the image cycle
                if (total === 0) {
                    $('#top_img').fadeIn();
     
                    var t = setTimeout(function() {
                        cycle(images);
                    }, delay);
                }
            }).attr('src', this.src);
        });
    });

  5. #5
    SitePoint Addict
    Join Date
    Oct 2009
    Location
    London, UK
    Posts
    382
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Hi Chris,

    Thanks for your reply. I've been round the houses with this one a little because jQuery will change the display property of elements to block on fadeIn(), but it's important for my images to remain inline. So I've reverted back to changing the background image of the top_img and next_img div.

    The problem is again the array is empty when I send it to the cycle function.

    jQuery:
    Code:
    var delay = 5000, images = [], total;
    
    function cycle(images){
      var topImg = $('#top_img'), nextImg = $('#next_img');
      var currentImg = topImg.css("background-image").match(/url\((.+)\)/)[1];
      var i = $.inArray(currentImg, images);
      var length = images.length;
      var nextI = i+1 > images.length ? 0 : i+1;
      nextImg.css({backgroundImage: "url(" + images[nextI] + ")"});
      topImg.fadeOut(function(){
        topImg.css({backgroundImage: "url(" + images[nextI] + ")"}).show();
      });
    }
    
    $(document).ready(function(){
      var length = $('#main_img img').length;
      $('#main_img').append('<div id="top_img"></div><div id="next_img"></div>');
      $('#top_img').hide();
      $('img', '#main_img').each(function(){
        images.push(this.src);
        $(this).load(function(){
        $(this).remove();
      });
      length--;
      if(length === 0){
        console.log(images) // output : ['http://locahost/images/blahblah.jpeg', 'http://locahost/images/blahblah2.jpeg']
        $('#top_img').css({backgroundImage: "url(" + images[0] + ")"}).fadeIn(function(){
          console.log(images) // output : []
          t = setTimeout(function(){cycle(images)}, delay);
        });
      }
    });
    If I try:
    Code:
      if(length === 0){
        $('#top_img').css({backgroundImage: "url(" + images[0] + ")"}).fadeIn(function(images){  // images array declared in anonymous function
          console.log(images) // output : undefined
          t = setTimeout(function(){cycle(images)}, delay);
        });
      }
    I am confused.com...


Tags for this Thread

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
  •