Необходимо отображать видеоконтроль HTML5 при наведении или воспроизведении
Я хотел бы скрыть элементы управления для нескольких HTML5-видео на странице. Если пользователь наводил курсор на видео, должны отображаться элементы управления. Если они нажимают кнопку воспроизведения, элементы управления должны оставаться видимыми, даже если их мышь покидает элемент видео.
Я не могу заставить это работать, используя следующий код. Может ли кто-нибудь выявить проблему?
var $video = $('.video');
$video.on('mouseover', show);
$video.on('mouseleave', hide);
function show() {
$(this).attr('controls', '');
}
function hide() {
var isPlaying = false;
this.onplaying = function() {
isPlaying = true;
}
if (!isPlaying) {
$(this).removeAttr('controls');
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<video class="video">
<source src="http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4" type="video/mp4">
</video>
Ответы
Ответ 1
Мы не можем контролировать это поведение, поскольку он управляется браузером. Все, что мы можем сделать, это указать атрибут controls
, а браузер сделает все остальное.
Например: в Firefox (v59b, когда это написано) элементы управления будут исчезать, когда мышь находится вне элемента, когда воспроизводится видео, даже если установлен атрибут controls
- они будут отображаться, если не воспроизводятся, наоборот, вы после. Невозможно заставить элементы управления оставаться видимыми, когда пользователь перемещает мышь вне видеоэлемента.
Единственный способ правильно обработать этот кросс-браузер и с точным желаемым поведением - создать пользовательский интерфейс пользовательских элементов управления для проигрывателя. Это, конечно, означает, что для обработки различных событий требуется больше кода, чтобы вы могли обновлять и управлять пользовательским интерфейсом; это также может быть проблемой, когда речь заходит о конкретном взгляде на платформу/браузер. Но это, с другой стороны, даст вам контроль над зерном.
Альтернативой является просмотр некоторых библиотек, которые обертывают элемент видео в пользовательские элементы управления пользовательским интерфейсом и видят, позволяют ли они заставить элементы управления оставаться видимыми при заданных условиях. В качестве отправной точки смотрите videojs.
Небольшой, но неполный пример (добавьте функциональность, обработчики событий, при необходимости создайте):
var $container = $("#video1");
var $video = $container.children("video"), video = $video[0]
var $controls = $container.children(".controls");
var $play = $controls.children("button");
// control visibility
$container.on("mouseover mouseout", function(e) {
$controls.css("display", e.type === "mouseout" && video.paused ? "none" : "block");
});
// play or pause
$play.on("click", toggle);
$video.on("click", toggle);
function toggle() {
video[video.paused ? "play" : "pause"]();
}
// todo: cover more events (seeked, error etc.)
$video.on("play pause ended", updateUI);
// update control UI elements (todo: update time/progress etc.)
function updateUI() {
$play.text(video.paused ? "Play" : "Pause")
}
.container {
position:relative;
display:inline-block;
font-size:0;
}
.container > .controls {
position:absolute;
bottom:0;
width:100%;
background:rgba(255,255,255,0.3);
padding:7px;
box-sizing:content-box;
z-index:10000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id=video1 class=container>
<video width=640 muted src="//media.w3.org/2010/05/sintel/trailer.mp4"></video>
<div class=controls style="display:none">
<button>Play</button>
</div>
</div>
Ответ 2
Проверьте этот код. его работа в соответствии с вашими требованиями. использовать "$ ('. video" ). get (0).paused "function in if условие для установки isplaying = True.
var $video = $('.video');
$video.on('mouseover', show);
$video.on('mouseleave', hide);
function show() {
$(this).attr('controls', '');
}
function hide() {
var isPlaying = false;
if(!$('.video').get(0).paused) {
isPlaying = true;
}
if (!isPlaying) {
$(this).removeAttr('controls');
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<video class="video">
<source src="http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4" type="video/mp4">
</video>
Ответ 3
Независимо от того, что вы установили в обработчике onplaying
, вы по-прежнему устанавливаете isPlaying
как false при каждом выполнении show()
, чтобы он всегда удалял элементы управления. Попытайтесь немного изменить свою логику. Как и ручка, когда видео останавливается, приостанавливается или иным образом изменяется состояние. Используйте те, чтобы изменить свою логику, показывая элементы управления.
Ответ 4
Обновлено - единственным решением для браузера является пользовательский контроль
Элементы управления Chrome и Firefox видны при наведении и воспроизведении. В качестве бонусного бонуса он реагирует. Примечание. Если вы хотите, чтобы он правильно функционировал для Firefox и Chrome в полноэкранном режиме, см. Plunker 🟊.
Похоже, что при воспроизведении видео не удается отображать элементы управления, если не запущено событие mousemove. Сначала я понял, что если бы мы могли перемещать мышь 1px туда и обратно, это было бы решением, хотя и хакерским и ресурсоемким. К сожалению, перемещение курсора мыши программно невозможно, потому что никто не очень ценит, что их мышь захвачена, независимо от того, насколько невиновны намерения разработчика.
Сначала я думал, что .focus()
будет работать, но не для Firefox, поэтому, пытаясь найти решение для простого кроссбраузерного поведения, оно сводилось к полностью удалению элементов управления и созданию настраиваемых элементов управления. Он включает в себя тонну специальных стилей, характерных для каждого браузера. См. Эту статью: Создание пользовательского видеопроигрывателя HTML5 и DOM DOM. Следующая демо - это многопользовательская версия jQuery статьи демо. Подробнее см. README.md.
Plunker 🟊
Демо - пользовательские элементы управления - Примечание: Firefox и Chrome в полноэкранном режиме см. Plunker 🟊.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<style>
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
body {
padding: 0;
display: flex;
flex-flow: column nowrap;
min-height: 100vh;
background: linear-gradient(135def, #7c1599 0%, #921099 48%, #7e4ae8 100%);
background-size: cover;
align-items: center;
justify-content: center;
}
.cover {
max-width: 750px;
border: 5px solid rgba(0, 0, 0, 0.2);
box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
position: relative;
font-size: 0;
overflow: hidden;
}
.video {
width: 100%;
}
.toggle {
background: none;
border: 0;
line-height: 1;
color: white;
text-align: center;
outline: 0;
padding: 0;
cursor: pointer;
max-width: 50px;
}
.toggle:focus {
border-color: #ffc600;
}
.volume {
width: 10px;
height: 30px;
}
.panel {
display: flex;
position: absolute;
bottom: 0;
width: 100%;
transform: translateY(100%) translateY(-5px);
transition: all 0.3s;
flex-wrap: wrap;
background: rgba(0, 0, 0, 0.1);
z-index: 2147483648;
left: 0;
}
.cover:hover .panel,
.panel.active {
transform: translateY(0);
}
.panel:hover .progress,
.panel.active .progress {
height: 15px;
}
.panel > * {
flex: 1;
}
.progress {
flex: 10;
position: relative;
display: flex;
flex-basis: 100%;
height: 5px;
transition: height 0.3s;
background: rgba(0, 0, 0, 0.5);
cursor: ew-resize;
}
.bar {
width: 50%;
background: #ffc600;
flex: 0;
flex-basis: 50%;
}
/* unholy css to style input type="range" */
input[type=range] {
-webkit-appearance: none;
background: transparent;
width: 100%;
margin: 12px 3px;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 5px;
cursor: pointer;
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0), 0px 0px 1px rgba(13, 13, 13, 0);
background: rgba(255, 255, 255, 0.8);
border-radius: 1.3px;
border: 0.2px solid rgba(1, 1, 1, 0);
}
input[type=range]::-webkit-slider-thumb {
box-shadow: 0 0 0 rgba(0, 0, 0, 0), 0 0 0 rgba(13, 13, 13, 0);
height: 1.5em;
width: 1.5em;
border-radius: 20px;
background: #ffc600;
cursor: pointer;
-webkit-appearance: none;
margin-top: -8px;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #ffc600;
}
input[type=range]::-moz-range-track {
width: 100%;
height: 3px;
cursor: pointer;
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0), 0px 0px 1px rgba(13, 13, 13, 0);
background: #fff;
border-radius: 1.3px;
border: 0.2px solid rgba(1, 1, 1, 0);
}
input[type=range]::-moz-range-thumb {
box-shadow: 0px 0px 0px rgba(0, 0, 0, 0), 0px 0px 0px rgba(13, 13, 13, 0);
height: 1.5em;
width: 1.5em;
border: 0;
border-radius: 20px;
background: #ffc600;
cursor: pointer;
}
/* full screen button styling */
.fullscreen {
margin-right: 7px;
background: none;
border: 1px solid white;
border: 0;
line-height: 1;
color: white;
text-align: center;
outline: 0;
padding: 0 0 5px 0;
cursor: pointer;
max-width: 30px;
font-size: 1.3rem;
}
/* Because video needed a defined hieght in order for object-fit: fill to work. */
video {
height: 100%;
object-fit: fill;
}
/* hide the default Chrome video player styling */
video::-webkit-media-controls-overlay-enclosure {
display: none !important;
}
video::-webkit-media-controls-enclosure {
display: none !important;
}
video::-webkit-media-controls {
display: none !important;
}
/* Needed to hide player controls in Safari Only */
video::-webkit-media-controls-panel {
display: none !important;
}
video::-webkit-media-controls-play-button {
display: none !important;
}
video::-webkit-media-controls-current-time-display {
display: none !important;
}
video::-webkit-media-controls-time-remaining-display {
display: none !important;
}
video::-webkit-media-controls-timeline {
display: none !important;
}
video::-webkit-media-controls-mute-button {
display: none !important;
}
video::-webkit-media-controls-volume-slider {
display: none !important;
}
video::-webkit-media-controls-fullscreen-button {
display: none !important;
}
video::-internal-media-controls-download-button {
display: none !important;
}
/* Firefox Shadow DOM Fix */
*::-moz-list-bullet,
*::-moz-list-number {
display: none !important;
}
*::-moz-meter-bar {
display: none !important;
}
:-moz-full-screen:not(:root)::backdrop {
display: none !important;
}
*::backdrop {
display: none !important;
}
:fullscreen:not(:root) {
display: none !important;
}
/* New addition to removal of User Agent StyleSheet for Firefox. Removed dotted border around range. */
input[type="range"]::-moz-focus-outer {
border: 0;
}
</style>
</head>
<body>
<div id='V0' class='cover'></div>
<div id='V1' class='cover'></div>
<div id='V2' class='cover'></div>
<div id='V3' class='cover'></div>
<template id='controls'>
<div class="panel">
<div class="progress">
<div class="bar"></div>
</div>
<button class="toggle" title="Play/Pause">
<i class="fa fa-play fa-3x"></i>
</button>
<input type="range" class="volume" min="0" max="1" step="0.05" value="0.70">
<button class='fullscreen'>
<i class='fa fa-expand fa-2x'></i>
</button>
</div>
</template>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
var mp4 = ['005609.mp4', '005610.mp4', '005611.mp4', '005612.mp4'];
var webm = ['041157.mp4', '041153.mp4', '041154.mp4', '041156.mp4'];
function init(VMp4, VWebm) {
var VArray = Array.from(document.querySelectorAll('.cover'));
VArray.map(function(V, idx) {
var ID = V.id;
return players(ID, idx, VMp4, VWebm);
});
}
function players(id, IDX, vMp4, vWebm) {
var V = document.getElementById(id);
console.log(V);
var frag = document.createDocumentFragment();
var tag = document.createElement('video');
var src0 = document.createElement('source');
var src1 = document.createElement('source');
tag.classList.add('video');
tag.controls = false;
tag.width = '320';
tag.style.background = '#000';
tag.poster = `https://gincore.net/images/video-play-2.png`;
// Set Paths
var mUrl = `https://storage04.dropshots.com/photos6000/photos/1381926/20170326/`;
var wUrl = `https://storage04.dropshots.com/photos7000/photos/1381926/20180214/`;
src0.type = 'video/mp4';
src1.type = 'video/webm';
src0.src = mUrl + vMp4[IDX];
src1.src = wUrl + vWebm[IDX];
frag.appendChild(tag);
tag.appendChild(src0);
tag.appendChild(src1);
V.appendChild(frag);
var controls = document.querySelector('#controls').content;
var clone = document.importNode(controls, true);
V.appendChild(clone);
}
init(mp4, webm);
$(".cover").each(function() {
var C = $(this)[0].id;
var $ctl = $(this).find('.panel');
var $vid = $(this).find('.video');
var $tog = $(this).find('.toggle');
var $prg = $(this).find('.progress');
var $bar = $(this).find('.bar');
var $vol = $(this).find('.volume');
var $tfs = $(this).find('.fullscreen')
var ctl = $ctl[0];
var vid = $vid[0];
var tog = $tog[0];
var prg = $prg[0];
var bar = $bar[0];
var vol = $vol[0];
var tfs = $tfs[0];
function togglePlay() {
var playPause = vid.paused ? 'play' : 'pause';
vid[playPause]();
$tog.find('.fa').toggleClass('fa-play fa-pause');
}
function updateVolume() {
vid.volume = this.value;
}
function updateProgress() {
var perc = (vid.currentTime / vid.duration) * 100;
bar.style.flexBasis = `${perc}%`;
}
function seekTrack(e) {
var seekTime = (e.offsetX / prg.offsetWidth) * vid.duration;
vid.currentTime = seekTime;
}
var isFullScreen = function() {
return !!(document.webkitFullscreenElement || document.mozFullScreenElement || document.fullscreenElement);
};
function toggleFS() {
if (!isFullScreen()) {
if (vid.requestFullscreen) {
vid.requestFullscreen();
} else if (vid.webkitRequestFullScreen) {
vid.webkitRequestFullScreen();
} else if (document.getElementById(C).mozRequestFullScreen) {
document.getElementById(C).mozRequestFullScreen();
} else if (vid.msRequestFullscreen) {
vid.msRequestFullscreen();
}
$tfs.find('.fa').removeClass('fa-expand').addClass('fa-compress');
$ctl.removeClass('active');
$('.panel').css('z-index', '-1');
$('#' + C + " .panel").css('z-index',"2147483648");
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.msCancelFullscreen) {
document.msCancelFullscreen();
}
$tfs.find('.fa').addClass('fa-expand').removeClass('fa-compress');
if (!vid.pause || !vid.ended) {
$ctl.addClass('active');
}
$('.panel').css('z-index', '2147483648');
}
}
function go() {
$ctl.addClass('active');
$tog.find('.fa').removeClass('fa-play').addClass('fa-pause');
}
function stop() {
$ctl.removeClass('active');
$tog.find('.fa').removeClass('fa-pause').addClass('fa-play');
}
$vid.on('click', togglePlay);
$tog.on('click', togglePlay);
$vid.on('timeupdate', updateProgress);
$vid.on('playing', go);
$vid.on('ended pause', stop);
$vol.on('input', updateVolume);
var mousedown = false;
$prg.on('click', seekTrack);
$prg.on('mousemove', function(e) {
mousedown && seekTrack(e);
});
$prg.on('mousedown', function() {
mousedown = true;
});
$prg.on('mouseup', function() {
mousedown = false;
});
$tfs.on('click', toggleFS);
});
</script>
</body>
</html>
Ответ 5
Может ли этот пример помочь.
Элемент элементов управления является логическим:
// by id video.
document.getElementById("video1").controls = true; //show
document.getElementById("video1").controls = false; //hide.
//or all video by tag name:
document.getElementsByTagName("video").controls = true; //show
document.getElementsByTagName("video").controls = false; //hide.
Ответ 6
Вы можете сделать это довольно легко в любых браузерах на основе webkit. Ниже приведен пример автономного примера с встроенным js, включая поддержку доступа к клавиатуре.
Сохранение контроля во время игры является самым сложным аспектом. Это требует псевдоселекторов CSS или доступа к теневому домику медиаплеера. Если вам нужно поддерживать Firefox, вам может потребоваться изучить стиль тени (или создать пользовательские элементы управления).
video[controls]::-webkit-media-controls-panel {
display: flex !important;
opacity: 1 !important;
}
/* not required */
video { width: 15em; height: auto; }
/* /not required */
<video
src="https://cdn.jsdelivr.net/npm/[email protected]/video.mp4"
type="video/mp4"
onmouseover="dataset.over=true;controls=true"
onmouseout="delete dataset.over;if(paused) controls=false;"
onplay="controls=true"
onpause="if(!dataset.over && !dataset.focus) controls=false"
onfocusin="dataset.focus=true; controls=true"
onfocusout="delete dataset.focus; if(paused) controls=false;"
></video>
<video src="https://cdn.jsdelivr.net/npm/[email protected]/video.mp4" type="video/mp4" onmouseover="dataset.over=true;controls=true" onmouseout="delete dataset.over;if(paused)controls=false;" onplay="controls=true" onpause="if(!dataset.over&&!dataset.focus)controls=false" onfocusin="dataset.focus=true; controls=true" onfocusout="delete dataset.focus;if(paused)controls=false;"></video>
Ответ 7
Я создал пример в fiddle. К сожалению, это работает только в браузерах на базе веб-браузера или Chrome, таких как Chrome и Safari.
Здесь также фрагмент:
var $video = $('.video');
$video.on('mouseover', show);
$video.on('mouseleave', hide);
$video.on('playing', function() {
$video.isPlaying = true;
});
$video.on('pause abort', function() {
$video.isPlaying = false;
});
function show() {
if (!$(this).attr('controls'))
$(this).attr('controls', '');
}
function hide() {
if (!$video.isPlaying) {
if ($(this).attr('controls'))
$(this).removeAttr('controls');
}
}
video[controls]::-webkit-media-controls-panel {
display: flex !important;
opacity: 1 !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<video class="video">
<source src="http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4" type="video/mp4">
</video>
Ответ 8
Супер легкий! Посмотрите мой JSFiddle, здесь.
<script src=https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js></script><video class=video><source src=http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4 type=video/mp4></video><style>video[controls]::-webkit-media-controls-panel{display:flex!important;opacity:1!important}</style><script>var $video=$(".video");$video.on("mouseover",function(){this.dataset.over=!0,this.controls=!0}),$video.on("mouseout",function(){delete this.dataset.over,this.paused&&(this.controls=!1)})</script>