How to Fix Event Conflicts Between Swiper and Video.Js

Viewed 5140

I'm using Swiper for a simple slideshow with images and videos. This works like a charm. However, because a design requirement is to have a consistent and nice looking player UI, I need to use Video.js as a video player. So I have Swiper as slideshow plugin and Video.js as video plugin. This is working except that there are event conflicts between these two plugins.

Swiper has a mousedown event on its root, while Video.js has a mousedown event too, on the video and its (dynamically created by Video.js) parent container. When dragging the slide (the video) not only Swiper detects that it must swipe, but also Video.js will handle this as click on the video. Therefore if you swipe to a next slide, this always means that the video is played/paused.

Also, when you drag the circle on the timeline Swiper also detects a swipe.

Is there any chance to patch both event listeners to work together? I'm searching a way without patching the libraries itself. Also the patch should not affect the original behavior of the plugins.

Here's the code I'm reffering to. You can also play with this jsfiddle.

var swiper = new Swiper('.swiper-container', {
  pagination: '.swiper-pagination',
  paginationClickable: true,
  nextButton: '.swiper-button-next',
  prevButton: '.swiper-button-prev',
  spaceBetween: 30
});

[...document.querySelectorAll('video')].forEach(video => {
  video.classList.add('video-js');
  video.classList.add('vjs-default-skin');
  video.classList.add('vjs-big-play-centered');
  videojs(video, {
    fluid: true,
    autoplay: true
  });
});
html,
body {
  position: relative;
  height: 100%;
}

body {
  background: #eee;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
  font-size: 14px;
  color: #000;
  margin: 0;
  padding: 0;
}

.swiper-container {
  width: 100%;
  height: 100%;
}

.swiper-slide {
  text-align: center;
  font-size: 18px;
  background: #fff;
  /* Center slide text vertically */
  display: -webkit-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  -webkit-justify-content: center;
  justify-content: center;
  -webkit-box-align: center;
  -ms-flex-align: center;
  -webkit-align-items: center;
  align-items: center;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/3.4.2/css/swiper.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/3.4.2/js/swiper.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/video.js/6.2.5/video-js.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/video.js/6.2.5/video.min.js"></script>

<!-- Swiper -->
<div class="swiper-container">
  <div class="swiper-wrapper">
    <div class="swiper-slide">
      <video preload="auto" muted loop controls>
        <source src="https://dwknz3zfy9iu1.cloudfront.net/uscenes_h-264_hd_test.mp4" type="video/mp4">
      </video>
    </div>
    <div class="swiper-slide">Slide 2</div>
    <div class="swiper-slide">
      <video preload="auto" muted loop controls>
        <source src="https://dwknz3zfy9iu1.cloudfront.net/uscenes_h-264_hd_test.mp4" type="video/mp4">
      </video>
    </div>
    <div class="swiper-slide">Slide 4</div>
    <div class="swiper-slide">Slide 5</div>
    <div class="swiper-slide">Slide 6</div>
    <div class="swiper-slide">Slide 7</div>
    <div class="swiper-slide">Slide 8</div>
    <div class="swiper-slide">Slide 9</div>
    <div class="swiper-slide">Slide 10</div>
  </div>
  <!-- Add Pagination -->
  <div class="swiper-pagination"></div>
  <!-- Add Arrows -->
  <div class="swiper-button-next"></div>
  <div class="swiper-button-prev"></div>
</div>

4 Answers

This will set no swiper only for the control bar of video js.

$( ".vjs-control-bar" ).addClass('swiper-no-swiping');

Swipe still works on the video div.

Similar to Manev's answer, init Swiper with the option noSwipingClass: 'vjs-control-bar' would also work.

var swiper = new Swiper('.swiper-container', {
  noSwipingClass: 'vjs-control-bar'
});
Related