Search code examples
jqueryhtmlvideojquery-cycle2cycle2

Cycle 2 HTML 5 Video Plugin play/pauze only works on odd not even


So I am making a HTML5 Video plugin for the Cycle2 Slideshow Plugin.

What is working:

First slide video autoplay, if video is finished it automatically goes to next slide. If that next slide is a video it autoplays that one. If you switch between slides then the previous video slide is paused and the new slide is played. Timeout is disabled on video slides so the entire video gets played

What is not working:

Play/Pauze video element when clicking on the .cycle-slideshow. This is partially working! What happens is that p/p works perfect the first time you see a slide but the 2nd time you see that slide it ain't working. The 3rd time it does. The 4th time it does not.

So on ODD it works and on EVEN it does not!

The Code

/*! html5video plugin for Cycle2;  version: 00000001 */
(function($) {
$(document).ready(function() {
// We add a class for targetting
$('.lsss-video').parent().addClass('cycle-slide-html5video');

// We assign a id to this class
$('.cycle-slide-html5video').attr('id', 'lsss-video');

// Autoplay the video in the first slide on page load and after each transition
$( '.cycle-slideshow' ).on( 'cycle-update-view', function(event, optionHash, slideOptionsHash, currentSlideEl) {
  // Before we give the command we need to check if the slide contains a video element
  if ($(currentSlideEl).is('#lsss-video')) {
    // Video element is present so we continue with playing the video
    $('video', currentSlideEl)[0].play();
    // Now we want to assign a class 'playing' to this video element only so we can play/pause it
    $('video', currentSlideEl)[0].addClass('playing');
    // We want to click on the slideshow to make it play/pause
    $(".cycle-slideshow").click(function() {
      console.log('clicked');
      // Now we check if the 'playing' class is present if it is we continue with play/pause
      if ($('video', currentSlideEl)[0].hasClass('playing')) {
        // Playing class is present so we continue with a click function
        console.log('The playing class is found!');
          // Now we pause the video and remove the `playing` class and add the `paused` class
          $('video', currentSlideEl)[0].pause();
          $('video', currentSlideEl)[0].removeClass('playing');
          $('video', currentSlideEl)[0].addClass('paused');
      // As the `playing` class was not present we continue to see if it was already `paused`
      } else if ($('video', currentSlideEl)[0].hasClass('paused')) {
        // Pause class is present so we continue with a click function
        console.log('The paused class is found!');
          // Now we play the video and remove the `paused` class and add the `playing` class
          $('video', currentSlideEl)[0].play();
          $('video', currentSlideEl)[0].removeClass('paused');
          $('video', currentSlideEl)[0].addClass('playing');
      }
    });
  }
});

// We pauze the previous video when the user advances to a new slide
$( '.cycle-slideshow' ).on( 'cycle-before', function(event, optionHash, outgoingSlideEl, incomingSlideEl, forwardFlag) {
  // Before we give the command we need to check if the slide contains a video element
  if ($(outgoingSlideEl).is('#lsss-video')) {
    // Video element is present so we continue with pauzing the video
    $('video', outgoingSlideEl)[0].pause();
    // We remove any left behind classes from the previous element
    $('video', outgoingSlideEl)[0].removeClass('paused');
    $('video', outgoingSlideEl)[0].removeClass('playing');
  }
});

// When the video is playing we don't want the timeout to interrupt it so on the video elements we override the timeout
$('#lsss-video').attr('data-cycle-timeout', '0');

// When the video is done playing we want it to automatically advance the slide to the next one
$('video').on('ended',function(){
  //console.log('Video has ended!');
  $(this).closest('.cycle-slideshow').cycle('next'); // trigger next slide
});

});// Document Ready
})(jQuery);

Solution

  • You can find a full working exemple in this fiddle :

    https://jsfiddle.net/Tintin37/z1hgg3mw/

    /*! html5video plugin for Cycle2;  version: 00000001 */
    (function($) {
      $(document).ready(function() {
        // We start with targetting the entire slideshow element
        $('.cycle-slideshow').each(function(i) {
          $(this).addClass('cycle-slideshow-randomid--' + i);
        }); // Cycle Slideshow Each Function
    
        // We add a class for targetting the video slides
        $('.lsss-video').parent().addClass('cycle-slide-html5video');
    
        // We assign a id to this class
        $('.cycle-slide-html5video').attr('id', 'lsss-video');
    
        // Autoplay the video in the first slide on page load and after each transition
        $('.cycle-slideshow').on('cycle-update-view', function(event, optionHash, slideOptionsHash, currentSlideEl) {
          // Before we give the command we need to check if the slide contains a video element
          if ($(currentSlideEl).is('#lsss-video')) {
            // Video element is present so we continue with playing the video
            $('video', currentSlideEl)[0].play();
          }
          // Leaves us with checking if the video should be playing or is paused
          // When paused
          $('.cycle-slideshow').on('cycle-paused', function(event, optionHash) {
            // We check if the currentslide is a video slide
            if ($(currentSlideEl).is('#lsss-video') && $(this).attr("class")==$(currentSlideEl).parent().attr("class")) {
              // Then we set the video on pause
    
              $('video', currentSlideEl)[0].pause();
            }
          });
          // When playing
          $('.cycle-slideshow').on('cycle-resumed', function(event, optionHash) {
            // We check if the currentslide is a video slide
            if ($(currentSlideEl).is('#lsss-video') && $(this).attr("class")==$(currentSlideEl).parent().attr("class")) {
              // Then we set the video on playing
              $('video', currentSlideEl)[0].play();
            }
          });
    
    
        });
    
        // We pauze the previous video when the user advances to a new slide
        $('.cycle-slideshow').on('cycle-before', function(event, optionHash, outgoingSlideEl, incomingSlideEl, forwardFlag) {
          // Before we give the command we need to check if the slide contains a video element
          if ($(outgoingSlideEl).is('#lsss-video')) {
            // Video element is present so we continue with pauzing the video
            $('video', outgoingSlideEl)[0].pause();
          }
          // Leaves us with checking if the video should be playing or is paused
          // When paused
          $('.cycle-slideshow').on('cycle-paused', function(event, optionHash) {
            // We check if the currentslide is a video slide
            if ($(outgoingSlideEl).is('#lsss-video') && $(this).attr("class")==$(outgoingSlideEl).parent().attr("class")) {
              // Then we set the video on pause
              $('video', outgoingSlideEl)[0].pause();
            }
          });
          // When playing
          $('.cycle-slideshow').on('cycle-resumed', function(event, optionHash) {
            // We check if the currentslide is a video slide
            if ($(outgoingSlideEl).is('#lsss-video') && $(this).attr("class")==$(outgoingSlideEl).parent().attr("class")) {
              // Then we set the video also on pause
              // We do this so that no matter what the previous video is always paused
              // On next view of that slide the `cycle-update-view` will take care of autoplaying
              $('video', outgoingSlideEl)[0].pause();
            }
          });
        });
    
        // When the video is playing we don't want the timeout to interrupt it so on the video elements we override the timeout
        $('#lsss-video').attr('data-cycle-timeout', '0');
    
        // When the video is done playing we want it to automatically advance the slide to the next one
        $('video').on('ended', function() {
          //console.log('Video has ended!');
          $(this).closest('.cycle-slideshow').cycle('next'); // trigger next slide
        });
      }); // Document Ready
    })(jQuery);
    

    Have a great day ;)