Pause Flexslider when overlay is open

2020-03-03 09:44发布

问题:

We are currently working on a project that utilizes the Flexslider plugin (recently acquired by Woo Themes). We have multiple pop ups on this page and we want the slider to pause when the pop ups are active and resume when the pop ups close. The pause only works the first go 'round and the resuming the slider does not work. Below is the code we are using for the slider. I have tried switching out the "start" function with all available calls except the "end" call.

$w('#slider-frame').flexslider({
        animation: 'fade',
        directionNav: false,
        slideshowSpeed: 4000,
        controlNav: true,
        pauseOnHover: true,
        manualControls: '#indicator-dots li',
        start: function(slider){

            $w('.roi-click').click(function(){
                slider.trigger('mouseenter');
            });

            $w('div#ovrly, a#close').click(function(){
                slider.trigger('mouseleave');
            });

        }
    });

The link to the page is http://www.whitehardt.com/sandbox/whitehardt-v3.

Any help on this would be greatly appreciated.

回答1:

Edited

I think I figured out what's going on here. The problem is you have conflicting events going on.

  1. Flexslider starts the animation by doing setInterval and storing the interval ID in an internal state variable (slider.animatedSlides).
  2. Flexslider pauses when you hover over the slide. It does this by clearing the animation interval with clearInterval().
  3. You click the roi link in the slide, which pauses again, by clearing what is now a non-existant interval.
  4. The page has an overlay on it, which means you do a mouseleave on the Flexslider, so it starts the animation up again with setInterval() and stores the interval ID.
  5. You close the overlay, by clicking the close button or the overlay, at which point you call resume(), which also does a setInterval(), overwriting the stored interval ID. So, now you have two animations going, hence the double speed. Plus, next time you call pause(), it only has access to clear the last interval you set because it overwrote the stored ID. So, you can no longer clear the interval from step 3. So, you will be going between having a one interval animation going (slow), when you mouseenter and two when you mouseleave (fast).

Instead of pausing on the click, you could pause on #ovrly mouseover, and resume on click, because the mouseexit of the Flexslider would before the mouseover of the overlay.

$w('#slider-frame').flexslider({
    animation: 'fade',
    directionNav: false,
    slideshowSpeed: 4000,
    controlNav: true,
    pauseOnHover: true,
    manualControls: '#indicator-dots li',
    start: function(slider){
        $w('div#ovrly').mouseover(function(){
            slider.pause();
        });
        $w('div#ovrly, a#close').click(function() {
            slider.resume();
        });
    }
});

But, you may run into similar problems, depending on whether the mouse is over the slider or not when the overlay is closed... but I'm not sure. Ideally, Flexslider wouldn't start a new animation if one was already going. You could hack this into flexslider.js:

//FlexSlider: Automatic Slideshow Pause
slider.pause = function() {
  // Only pause if running
  if(slider.animatedSlides == null) {
      return;
  }

  clearInterval(slider.animatedSlides);

  // Clear the interval ID
  slider.animatedSlides = null;

  if (slider.vars.pausePlay) {
    slider.pausePlay.removeClass('pause').addClass('play').text(slider.vars.playText);
  }
}

//FlexSlider: Automatic Slideshow Start/Resume
slider.resume = function() {
  // Only resume if paused
  if(slider.animatedSlides != null) {
      return;
  }
  slider.animatedSlides = setInterval(slider.animateSlides, slider.vars.slideshowSpeed);
  if (slider.vars.pausePlay) {
    slider.pausePlay.removeClass('play').addClass('pause').text(slider.vars.pauseText);
  }
}

You could overload these functions in your start: parameter function.

This change will solve the fast speed and the fact that you can't pause again. You will still have the problem of the slider resuming when your overlay pops up. This can be solved with the mouseover solution I mentioned before.

Here is a fiddle that shows the mouseover solution: http://jsfiddle.net/jtbowden/TWN5t/

It looks as if you may not need the second hack, although it is better code.



回答2:

@Jeff B, thanks for the JS fix. Since it doesn't work with the 2.x branch of Flexslider I think it's just for 1.x

For those on 2.x, a fix has been submitted by nvartolomei: https://github.com/woothemes/FlexSlider/pull/322



回答3:

I faced the same issue working with brightcove+flexslider. here is my workaround:

before

        pausePlay: true,
        pauseText :"Pause",
        playText  :"Play"

then

video.addEventListener(BCMediaEvent.PLAY, function () {
    $('.flex-pauseplay .flex-pause').trigger('click');
});

video.addEventListener(BCMediaEvent.STOP, function () {
    $('.flex-pauseplay .flex-play').trigger('click');   
});

.flex-pauseplay .flex-play css opacity: 0