admin 管理员组文章数量: 1087132
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=".4.2/css/swiper.min.css" rel="stylesheet" />
<script src=".4.2/js/swiper.min.js"></script>
<link href=".js/6.2.5/video-js.min.css" rel="stylesheet" />
<script src=".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=".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=".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>
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./ajax/libs/Swiper/3.4.2/css/swiper.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare./ajax/libs/Swiper/3.4.2/js/swiper.min.js"></script>
<link href="https://cdnjs.cloudflare./ajax/libs/video.js/6.2.5/video-js.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare./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/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/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>
Share
Improve this question
edited Aug 5, 2017 at 8:08
dude
asked Aug 2, 2017 at 18:59
dudedude
6,10611 gold badges55 silver badges85 bronze badges
4 Answers
Reset to default 4 +100You can add a class to the option noSwipingClass
to prevent Swiper from processing events on slides with that class. Now only the next/prev Swiper buttons will work on video slides. Perhaps a reasonable promise.
eg.
var swiper = new Swiper('.swiper-container', {
nextButton: '.swiper-button-next',
prevButton: '.swiper-button-prev',
spaceBetween: 30,
noSwipingClass: 'swiper-no-swiping'
});
with:
<!-- Swiper -->
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide swiper-no-swiping" oncouseo>
<video preload="auto" muted loop controls>
<source src="https://dwknz3zfy9iu1.cloudfront/uscenes_h-264_hd_test.mp4" type="video/mp4">
</video>
</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide swiper-no-swiping">
<video preload="auto" muted loop controls>
<source src="https://dwknz3zfy9iu1.cloudfront/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>
<!-- Add Arrows -->
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
</div>
Demo: https://jsfiddle/zqhLqfck/
Another approach, but more inline with what you're asking, is to add an overlay over the video and only pass click events through to the video.
It stretches the overlay to the size of the video area whilst excluding the video control bar at the bottom.
In the div
that that is the control bar add the class 'swiper-no-swiping' to stop video gestures from being recognised by Swiper.
Now swiping on the overlay will not cause the video to play or pause, but clicking on it will and gestures for the video control bar will be ignored by Swiper.
Of course the visible CSS and text is just to help illustrate the overlay, and would be removed.
var swiper = new Swiper('.swiper-container', {
pagination: '.swiper-pagination',
paginationClickable: true,
nextButton: '.swiper-button-next',
prevButton: '.swiper-button-prev',
spaceBetween: 30,
noSwipingClass: 'swiper-no-swiping'
});
[...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
});
});
$(function() {
var $overlay = $("#video-overlay1");
var myPlayer = videojs('vid1');
var $overlayArea = $("#vid1 > .vjs-text-track-display");
// apply overlay on video to prevent swipes playing/pausing the video
positionVideoOverlay();
// prevent swiping action on video control bar
$(".vjs-control-bar").addClass("swiper-no-swiping");
$overlay.click(function() {
if (myPlayer.paused())
myPlayer.play();
else
myPlayer.pause();
});
$(window).resize(function() {
positionVideoOverlay();
});
function positionVideoOverlay() {
$overlay.css("width", $overlayArea.width() + "px");
$overlay.css("height", $overlayArea.height() + "px");
$overlay.css("top", $overlayArea.offset().top + "px")
}
});
.video-overlay {
position: absolute;
left: 0;
top: 0;
font-size: 20px;
font-family: Helvetica;
color: #FFF;
background-color: rgba(50, 50, 50, 0.8);
}
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">
<video id="vid1" preload="auto" muted loop controls>
<source src="https://dwknz3zfy9iu1.cloudfront/uscenes_h-264_hd_test.mp4" type="video/mp4">
</video>
<div id="video-overlay1" class="video-overlay">Overlay that will pass clicks to video layer
<br>But will not pass swipe gestures</div>
</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
</div>
<!-- Add Pagination -->
<div class="swiper-pagination"></div>
<!-- Add Arrows -->
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
</div>
Demo illustrating the basic concept: https://jsfiddle/1vqozv25/4/
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'
});
本文标签: javascriptHow to Fix Event Conflicts Between Swiper and VideoJsStack Overflow
版权声明:本文标题:javascript - How to Fix Event Conflicts Between Swiper and Video.Js - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1744074888a2529165.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论