Ответ 1
Используя плагин isInViewport и jQuery, здесь мой код для задачи
$('video').each(function(){
if ($(this).is(":in-viewport")) {
$(this)[0].play();
} else {
$(this)[0].pause();
}
})
Я заинтересован в настройке HTML-страницы с несколькими видеоклипами, чтобы каждый видеоклип воспроизводился только тогда, когда он виден, а затем приостанавливался, когда его не видно.
Я нашел этот прекрасный пример того, как это можно реализовать с помощью одного клипа, но я не смог изменить код для работы с несколькими клипами. Возможно, мне нужно преобразовать этот код в функцию для удобства повторного использования?
Вот что у меня есть (JS Bin, связанный выше, изменен на 2 клипа вместо одного).
Этот код работает только для одного из двух клипов.
<!DOCTYPE html>
<html>
<!-- Created using jsbin.com Source can be edited via http://jsbin.com/ocupor/1/edit
-->
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
<style>
#right {
position: absolute;
top: 2000px;
}
#video1 {
position: absolute;
left: 2000px;
top: 2000px;
}
#video2 {
position: absolute;
left: 2000px;
top: 3000px;
}
</style>
<style id="jsbin-css">
</style>
</head>
#
<body style="width: 4000px; height: 4000px;">
<div id="info"></div>
<div id="down">
scroll down please...
</div>
<div id="right">
scroll right please...
</div>
<video id="video1">
<source src="http://video-js.zencoder.com/oceans-clip.mp4"/>
</video>
<script>
var video = document.getElementById('video1'), fraction = 0.8;
function checkScroll() {
var x = video.offsetLeft, y = video.offsetTop, w = video.offsetWidth, h = video.offsetHeight, r = x + w, //right
b = y + h, //bottom
visibleX, visibleY, visible;
visibleX = Math.max(0, Math.min(w, window.pageXOffset + window.innerWidth - x, r - window.pageXOffset));
visibleY = Math.max(0, Math.min(h, window.pageYOffset + window.innerHeight - y, b - window.pageYOffset));
visible = visibleX * visibleY / (w * h);
if (visible > fraction) {
video.play();
} else {
video.pause();
}
}
checkScroll();
window.addEventListener('scroll', checkScroll, false);
window.addEventListener('resize', checkScroll, false);
</script>
<video id="video2">
<source src="http://video-js.zencoder.com/oceans-clip.mp4"/>
</video>
<script>
var video = document.getElementById('video2'), fraction = 0.8;
function checkScroll() {
var x = video.offsetLeft, y = video.offsetTop, w = video.offsetWidth, h = video.offsetHeight, r = x + w, //right
b = y + h, //bottom
visibleX, visibleY, visible;
visibleX = Math.max(0, Math.min(w, window.pageXOffset + window.innerWidth - x, r - window.pageXOffset));
visibleY = Math.max(0, Math.min(h, window.pageYOffset + window.innerHeight - y, b - window.pageYOffset));
visible = visibleX * visibleY / (w * h);
if (visible > fraction) {
video.play();
} else {
video.pause();
}
} checkScroll();
window.addEventListener('scroll', checkScroll, false);
window.addEventListener('resize', checkScroll, false);
</script>
</body>
</html>
Используя плагин isInViewport и jQuery, здесь мой код для задачи
$('video').each(function(){
if ($(this).is(":in-viewport")) {
$(this)[0].play();
} else {
$(this)[0].pause();
}
})
ОК, я думаю, это должно быть примерно так:
var videos = document.getElementsByTagName("video");
function checkScroll() {
for(var i = 0; i < videos.length; i++) {
var video = videos[i];
var x = video.offsetLeft, y = video.offsetTop, w = video.offsetWidth, h = video.offsetHeight, r = x + w, //right
b = y + h, //bottom
visibleX, visibleY, visible;
visibleX = Math.max(0, Math.min(w, window.pageXOffset + window.innerWidth - x, r - window.pageXOffset));
visibleY = Math.max(0, Math.min(h, window.pageYOffset + window.innerHeight - y, b - window.pageYOffset));
visible = visibleX * visibleY / (w * h);
if (visible > fraction) {
video.play();
} else {
video.pause();
}
}
}
window.addEventListener('scroll', checkScroll, false);
window.addEventListener('resize', checkScroll, false);
Ничто из вышеперечисленного не показалось мне подходящим, но я наконец нашел способ: вам понадобится visible
плагин и этот маленький кусочек кода прямо здесь:
$(window).scroll(function() {
$('video').each(function() {
if ($(this).visible(true)) {
$(this)[0].play();
} else {
$(this)[0].pause();
}
})
});
Это позволит воспроизводить любое видео только тогда, когда оно попадает в область просмотра. Заменив visible( true )
на visible()
, вы можете настроить его на воспроизведение, только когда весь элемент DOM видео находится в области просмотра.
Необходимо проверить, видно ли видео во время прокрутки.
$(window).scroll(function() {
$('video').each(function(){
if ($(this).is(":in-viewport")) {
$(this)[0].play();
} else {
$(this)[0].pause();
}
})
});
Старый вопрос, но просто хотел добавить мои два цента, я сначала начал с кода jQuery выше, но столкнулся с некоторыми проблемами с реализацией. Это решение должно работать с несколькими видео, а также предотвращает проблему, когда пользователь приостанавливает видео и пытается прокрутить прочь, и он просто начинается снова:
<script>
var videoList = [];
var scrollPauseList = [];
var clickedPauseList = [];
</script>
<script>
var myScrollFunc = function() {
$(".video-js").each(function(){
var inView = $(this).is(":in-viewport");
var isPaused = $(this)[0].player.paused();
var playerIdx = videoList.indexOf(this.id);
var scrollPaused = scrollPauseList[playerIdx];
var clickPaused = clickedPauseList[playerIdx];
if (inView) {
var hasEnded = $(this)[0].player.ended();
var curTime = $(this)[0].player.currentTime();
var hasStarted = curTime > 0;
if(hasStarted && !hasEnded && !clickPaused)
{
scrollPauseList[playerIdx] = false;
$(this)[0].player.play();
}
} else if(!isPaused) {
scrollPauseList[playerIdx] = true;
$(this)[0].player.pause();
}
});
};
$(window).scroll(myScrollFunc);
</script>
<video
class="video-js" controls></video>
<script>
$(".video-js").each(function(){
videoList[videoList.length] = this.id;
scrollPauseList[scrollPauseList.length] = false;
clickedPauseList[scrollPauseList.length] = false;
});
for(var i = 0; i < videoList.length; i++)
{
var playerID = videoList[i];
var player = videojs(playerID);
player.on('pause', function() {
var pID = videoList.indexOf(this.id());
if(!scrollPauseList[pID])
{
clickedPauseList[pID] = true;
scrollPauseList[pID] = false;
}
else
{
clickedPauseList[pID] = false;
scrollPauseList[pID] = false;
}
});
}
</script>
Я очистил некоторые вещи, и я использую video-js, поэтому вам может понадобиться немного изменить его, чтобы ваша реализация работала.
Перепробовал много решений, единственное частично работающее - это то, которое выложено ниже. Проблема в том, что при наличии 3 видео на странице, второе и третье в основном контролируются первым.
Таким образом, они начинают играть, когда страница загружена (в то время как они должны играть, когда в окне просмотра), и они останавливаются, когда первый приостанавливается, есть ли какие-либо предложения по поводу того, чтобы это работало с несколькими видео?
Пробовал использовать getElementById
но не работал, пробовал также jquery плагины, но без хороших результатов.
Здесь у вас есть страница www, где вы можете увидеть, что происходит, и, конечно, весь исходный код.
http://185.197.128.183/~monompro/
window.onload = function() {
var videos = document.getElementsByTagName("video"),
fraction = 0.8;
function checkScroll() {
for (var i = 0; i < videos.length; i++) {
var video = videos[i];
var x = video.offsetLeft,
y = video.offsetTop,
w = video.offsetWidth,
h = video.offsetHeight,
r = x + w, //right
b = y + h, //bottom
visibleX, visibleY, visible;
visibleX = Math.max(0, Math.min(w, window.pageXOffset + window.innerWidth - x, r - window.pageXOffset));
visibleY = Math.max(0, Math.min(h, window.pageYOffset + window.innerHeight - y, b - window.pageYOffset));
visible = visibleX * visibleY / (w * h);
if (visible > fraction) {
video.play();
} else {
video.pause();
}
}
}
window.addEventListener('scroll', checkScroll, false);
window.addEventListener('resize', checkScroll, false);
}
В случае, если кто-то еще сталкивается с этим вопросом, мне не удалось использовать решение Saike на моем сайте WordPress из-за того, как видео было встроено в видео (MediaElement player). Однако решение qwazix работало с некоторыми изменениями. Вот код jQuery, который работает с плагин IsInView. Вот мои включенные сценарии (помещенные в конце footer.php
в папку темы).
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="js/isInViewport.min.js" type="text/javascript"></script>
<script src="js/scrollview.min.js" type="text/javascript"></script>
И код jQuery (измените 400 на ваш подход)
$(function() {
$(window).scroll(function() {
$('.wp-video-shortcode').each(function() {
var str = $(this).attr('id');
var arr = str.split('_');
typecheck = arr[0];
if ($(this).is(":in-viewport( 400 )") && typecheck == "mep") {
mejs.players[$(this).attr('id')].media.play();
} else if (typecheck == "mep") {
mejs.players[$(this).attr('id')].media.pause();
}
});
});
});
Только проблема с этим кодом заключается в том, что он перезапускает видеоклип на прокрутке, даже если он приостановлен пользователем. На моем сайте не была проблемой. Вот код в действии: Ultrasoundoftheweek.com
Используя jQuery, isInViewport и Coffeescript, полное решение для меня выглядело так:
$(window).scroll ->
$('video:in-viewport').each -> $(@)[0].play()
$('video:not(:in-viewport)').each -> $(@)[0].pause()
Вот как мне удалось воспроизвести видео только тогда, когда пользователь прокручивает его. Я использовал плагин IsInViewport. Надеюсь, вы сочтете это полезным!
$(window).scroll(function() {
var video = $('.yourvideo');
$(video).each(function(){
if(video.is(':in-viewport')){
video[0].play();
video.removeClass('yourvideo');
//I removed class to stop repeating the action ".play()" when it is scrolled again.
}
});
});
$('video').each(function(){
if ($(this).is(":in-viewport")) {
$(this)[0].play();
} else {
$(this)[0].pause();
}
})