2

I have a scrolling carousel of images and captions that interact separately but coordinate. Everything works great when I'm on the page/tab in IE, Firefox and Chrome. In FF and Chrome, however, once I go to another tab or browser for a little bit of time, the carousel scrolls wildly proportionately to the time I was away from that page.

It's almost as if it keeps up with the timer but does not advance the carousel until I come back to the page and then tries to catch up to where it should be, even if that is 10+ loops.

Obviously, this is not ideal and so any help would be greatly appreciated. Here is a link to the page: http://www.dillonsupply.com/default.aspx?page=customer&file=customer/disupp/customerpages/home_test_fader.htm

Here is my html:

    <div class="marquee_container autoplay">    
        <div class="marquee_photos"></div>
        <div class="marquee_caption">
            <div class="marquee_caption_content"></div>
        </div>
        <div class="marquee_nav"></div>
    </div>

    <div class="marquee_panels">
        <div class="marquee_panel">
            <img src="customer/disupp/images/fader/NewWebsiteRotator.jpg" class="marquee_panel_photo" alt="New Website" width="731" height="310" />
            <div class="marquee_panel_caption">
                <h2>LONDON</h2>
                <p>This is a test caption for San Diego.<br />This is a test caption for San Diego.</p>
                <p><a href="#">Check it out!</a></p>
            </div>
        </div>
        <div class="marquee_panel">
            <img src="customer/disupp/images/fader/1DaySale-DeWaltProto.gif" class="marquee_panel_photo" alt="DeWalt and Proto 1-Day Only Sale" width="731" />
            <div class="marquee_panel_caption">
                <h2>Up to 60% Off DeWalt and Proto Tool Sets</h2>
                <p>Mark you calendars for Thursday, December 15<sup>th</sup>. Don't miss out on your last chance this year to save big on the DeWalt and Stanley Proto tool sets you've been wanting.</p>
                <p><a href="customer/disupp/promo_files/DeWalt-Proto_Telesales.pdf" onClick="window.open('customer/disupp/promo_files/DeWalt-Proto_Telesales.pdf','popup','scrollbars=no,resizable=yes,toolbar=no,directories=no,location=no,menubar=no,status=no'); return false">Check it out!</a></p>
            </div>
        </div>
        <div class="marquee_panel">
            <img src="customer/disupp/images/fader/GatesRotator.jpg" class="marquee_panel_photo" alt="Gates" width="731" /><a href="http://www.dillonsupply.com/default.aspx?page=item%20search%20results&SearchFieldName=VendorItemSearch&SearchSource=BrandsList&selVendorName=%22Gates+Corporation%22&selVendorCode=Gates%20Corporation"><img src="customer/disupp/images/fader/GatesRotator-Button.png" width="116" height="25" style="position:absolute; bottom:18px; left:126px;"/></a>
            <div class="marquee_panel_caption">
                <h2>Gates</h2>
            </div>
        </div>
        <div class="marquee_panel">
            <img src="customer/disupp/images/fader/BursRotator.jpg" class="marquee_panel_photo" alt="Burs" width="731" />
            <div class="marquee_panel_caption">
                <h2>NYC</h2>
                <p>This is a test caption for NYC.<br />This is a test caption for NYC.</p>
                <p><a href="#">Check it out!</a></p>
            </div>
        </div>
    </div>

Here is the jQuery:

    var currentPanel = 1;
    var totalPanels = 0;
    var autoPlay = true;
    var timePassed = 0;
    var timeToChange = 6;

    $ (document).ready(function (){
        //Preload
        $('.marquee_panels img').imgpreload(function(){
            initializeMarquee();
        });

        setInterval(autoAdvance, 1000);

        if(window.autoPlay == true){
            $('.marquee_container').hover(
                function(){
                    window.autoPlay = false;
                    $(this).removeClass('autoplay');
                },
                function(){
                    window.autoPlay = true;
                    window.timePassed = 0;
                    $(this).addClass('autoplay');
                }
            );
        }

        //Generate Photo Lineup
        $('img.marquee_panel_photo').each(function (index){
            var photoWidth = $('.marquee_container').width();
            var photoPosition = index * photoWidth;
            $('.marquee_photos').append('<img class="marquee_photo"        style="left:'+photoPosition+'; display:inline-block" src="'+$(this).attr('src')+'" alt="'+$(this).attr('alt')+'" width="'+photoWidth+'" height="310" />');
            $('.marquee_photos').css('width' , photoPosition+photoWidth);
        });

        //Generate Navigation Links
        $('.marquee_panels .marquee_panel').each(function(index){
            $('.marquee_nav').append('<a class="marquee_nav_item"></a>');
            window.totalPanels = index + 1;
        });

        //Set up Navigation Links
        $('.marquee_nav a.marquee_nav_item').click(function(){

            //Set the navigation state
            $('.marquee_nav a.marquee_nav_item').removeClass('selected');
            $(this).addClass('selected');   

            var navClicked = $(this).index();
            var marqueeWidth = $('.marquee_container').width();
            var distanceToMove = marqueeWidth * (-1);  //slides to the left, positive 1 for slide to right
            var newPhotoPosition = navClicked * distanceToMove + 'px';
            var newCaption = $('.marquee_panel_caption').get(navClicked);
            window.currentPanel = navClicked + 1;

            //Animate the photos and caption
            $('.marquee_photos').animate({left: newPhotoPosition}, 1000);  //time interval to slide
            $('.marquee_caption').animate({top: '300px'}, 500, function (){
                var newHTML = $(newCaption).html();
                $('.marquee_caption_content').html(newHTML);
                setCaption();
            });
        });

    });

    function autoAdvance(){
        if(window.timePassed == window.timeToChange){
            window.timePassed = 0;
            if(window.currentPanel == window.totalPanels){
                window.currentPanel = 0;
            }
            if(window.autoPlay == true){
                $('.marquee_nav a.marquee_nav_item:nth-child('+       (window.currentPanel+1)+')').trigger('click');
            }
        }
        else{
            window.timePassed += 1;
        }
    }

    function initializeMarquee(){
        $('.marquee_caption_content').html(
            $('.marquee_panels .marquee_panel:first .marquee_panel_caption').html()
        );
        $('.marquee_nav a.marquee_nav_item:first').addClass('selected');
        $('.marquee_photos').fadeIn(1500);
        setCaption();
    }

    function setCaption(){
        var captionHeight = $('.marquee_caption').height();
        var marqueeHeight = $('.marquee_container').height();
        var newCaptionHeight = marqueeHeight - captionHeight - 15; //padding so that bottom of caption is away from bottom edge
        $('.marquee_caption').delay(100).animate({top: newCaptionHeight}, 500);
    }

Any help would be greatly appreciated. Thank you in advance.

**edit As I look at the marquee.js script, I'm wondering if it is the way I count the time before it the image/caption changes. I looked at an old slider script and it used a combination of duration and interval (one for the time it stayed on a page and the other for the time it took to change to the next slider). I'm not sure, however, how to change the autoAdvance function in order to reflect using duration and interval better.

rlphilli
  • 111
  • 1
  • 4
  • 17
  • First of all, up-vote for good question and well-formated code :). Secondly, I had almost the exact same issue with some jQuery/JS code I wrote a while back. I wasn't able to fix it properly, but my work-around was to detect when the page lost focus (i.e. user went to other tab) and kill all my timers until the page regained focus. Not elegant, but it got the job done. I'll definitely keep my eye on this question for a better solution! – The Maniac Dec 07 '11 at 18:03
  • Thanks, Maniac, for the reply. Did you use the .blur() event because I'm still trying to figure out how to get the page to read if it is still in focus. I can find info about focus for text boxes and such but not whole pages. Still looking at it. – rlphilli Dec 07 '11 at 20:10
  • Yes, I did use .blur/.focus. In fact, I used this Stackoverflow answer, and a few more hacks that were specific to my application: [Determine whether webpage has foreground window focus/is active tab?](http://stackoverflow.com/questions/3268298/determine-whether-webpage-has-foreground-window-focus-is-active-tab) – The Maniac Dec 07 '11 at 20:13
  • Thanks. I ended up using what I did in my second edit. You got me thinking on the right track for sure. – rlphilli Dec 07 '11 at 21:10

2 Answers2

1

If any one else is looking for an answer to this I found and alternative at jQuery (billy.carousel) - Carousel going nuts sometimes.

"You could also clear the object's fx queue with .clearQueue() right before the animation starts. At line 160 of billy.carousel.jquery.js:

object.clearQueue().animate({'marginLeft': "0"}, option.scrollSpeed);

"

This worked great and only required editing 1 line.

Community
  • 1
  • 1
AJK
  • 11
  • 1
1

I ended up using a script to see if the window was in focus and killed the marquee if it was not focused. Here is the script I used (found also http://www.thefutureoftheweb.com/blog/detect-browser-window-focus) with some adaptation for my purposes. Here is the piece of jquery I added to my marquee.js file:

    //Is the Window or Tab in focus
    function onBlur() {
            window.window_focus = false;
    };
    function onFocus(){
            window.window_focus = true;
    };

    if (/*@cc_on!@*/false) { // check for Internet Explorer
            document.onfocusin = onFocus;
            document.onfocusout = onBlur;
    } else {
            window.onfocus = onFocus;
            window.onblur = onBlur;
    }

And then below that in the same file, I edited the autoAdvance function to make the if statement conditional for both the autoplay and window_focus variables:

    function autoAdvance(){
        if(window.timePassed == window.timeToChange){
            window.timePassed = 0;
            if(window.currentPanel == window.totalPanels){
                window.currentPanel = 0;
            }
            if(window.autoPlay == true && window.window_focus == true){
                $('.marquee_nav a.marquee_nav_item:nth-child('+(window.currentPanel+1)+')').trigger('click');
            }
        }
        else{
            window.timePassed += 1;
        }
    }

It appears to be working in Firefox, IE8, and Chrome. I have not tested in all versions at this point. Thanks to The Maniac for pointing me in the correct direction.

rlphilli
  • 111
  • 1
  • 4
  • 17