When I try to click on video using js in Friefox click and display in console the id of the video it doesn't work. Why?
$('.videoclass').click(function() {
console.log(this);
var id = $(this).attr("id");
console.log(id);
})
<video controls="" id="ui-id-1" class="videoclass" style="position: absolute; top: 118px; left: 61px;" width="320" height="240"> <source id="videoavantuuid" src="https://www.w3schools.com/tags/movie.mp4" type="video/mp4"> </video>
Firefox controls is the Whole Video Tag
Problem
"When I try to click on video using js in Friefox Firefox click and display in console the id of the video it doesn't work. Why? "
Explanation
Firefox has a play button center poster and Chrome does not. This is an obvious indicator that FF has controls attribute that covers the entire tag and Chrome does not, it's controls are accessible only at the bottom where the bar is.
Firefox video tag is interpreting the click on it's controls property first so the click event registered on .vid is never fired or more likely event was fired then e.stopPropagation() was called so nothing else would be triggered by a click.
Recap
To summarize so far:
Firefox video tag behavior: responds to click events with play/pause but no other callbacks are triggered.
Firefox controls interacts with all click events directed to the video tag.
Solution ⭐
If you need controls on the video tag, then do not register the click event on the video tag. Register an alternate yet similar event instead:
mousedown,focus, contextmenu, etc.
Demo
Review the Demo with Firefox:
There's 3 video tags:
#ID [controls] Event Result on Firefox v.60.0.2
#vid0 ---- true ------ click --------- Plays video / Does not run callback
#vid1 --- false ------ click --------- Does not play video / Runs callback
#vid2 ---- true ------ focus --------- Plays video / Runs callback ⭐
$('.vid').on("click", identify);
$('.ff').on('focus', identify); //⭐
function identify(e) {
var eventcurrentTarget = e.currentTarget.id;
var eventTarget = e.target.id;
var thisId = this.id;
console.log({
eventcurrentTarget,
eventTarget,
thisId
});
}
figure {
width: 320px;
margin: 0 auto 20px 0
}
figcaption {
font-size: 32px
}
.as-console-wrapper {
margin-left: 325px;
width: 40%;
min-height: 96%
}
.as-console-row:after {
display: none !important
}
<figure>
<figcaption>#vid0</figcaption>
<video id="vid0" class="vid" width="320" height="240" controls>
<source src="https://www.w3schools.com/tags/movie.mp4" type="video/mp4">
</video>
</figure>
<figure>
<figcaption>#vid1</figcaption>
<video id="vid1" class="vid" width="320" height="240">
<source src="https://www.w3schools.com/tags/movie.mp4" type="video/mp4">
</video>
</figure>
<figure>
<figcaption>#vid2 ⭐</figcaption>
<video id="vid2" class="ff" width="320" height="240" controls>
<source src="https://www.w3schools.com/tags/movie.mp4" type="video/mp4">
</video>
</figure>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Change the below piece of the code
$('.videoclass').click(function() {
to
$(document).on('click', '.videoclass', function(){
and it should work.
Related
I am trying to have 2 different toggle videos as the hero. I will call them Video A and Video B. I want video A to autoplay on the homepage. I have a play button on video A. I want two things to happen when the play button is clicked:
hide Video A.
show video B.
I have successfully hidden Video A when the play button is clicked, but Video B is not visible (I can hear it playing, but cannot see it). I think it is a CSS problem, but am not sure.
Video B is too large to upload (I am using WordPress), so I have it as an iframe. Video A is within a video tag.
HTML:
<video playsinline autoplay muted loop id="poster-video" onclick="hideVid()">
<source src="video.mp4" type="video/mp4">
</video>
<div id="full-video" style="visibility:hidden" onclick="showVid()">
<iframe src="https://player.vimeo.com/video/?autoplay=1&loop=1&title=0&byline=0&portrait=0" frameborder="0" allow="autoplay; fullscreen" allowfullscreen>
</iframe>
</div>
<div id="xbut">
<span style="cursor:pointer" onclick="hideVid();showVid()">
<div class="ctrbutton"><img src="play-button-dark.png">
</div>
</span>
</div>
CSS:
video {
object-fit: cover;
width: 100vw;
position: absolute;
top: 0;
left: 0;
}
js:
function showVid() {
document.getElementById("full-video").style.display = "block";
}
function hideVid() {
document.getElementById("poster-video").style.display = "none";
}
when you hide video A also set video B visibility on true with
Trying to mute video using attr but it doesn't work.
HTML
<video autoplay muted class='preview-video'>
<source src='file.mp4' type='video/mp4'>
</video>
jQuery
function volumeToggle(button) {
var muted = $(".preview-video").attr("muted");
$(".preview-video").attr("muted", !muted)
}
However, when I try prop() instead of attr() it works. Can someone explain in detail the reason behind it?
You need to toggle the muted property of the video element, not the attribute. Try this:
let $vid = $('.preview-video');
$('button').on('click', function() {
$vid.prop('muted', (i, m) => !m);
});
video {
width: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Toggle Mute</button>
<video autoplay muted class='preview-video'>
<source src="http://grochtdreis.de/fuer-jsfiddle/video/sintel_trailer-480.mp4" type="video/mp4">
</video>
I'm struggling trying to set a mouseenter and mouseleave event in several videos. Everything seems that work perfectly, the video plays when I mouseenter and stop when mouseleave.
However, when I add more than one video, just play the first video. I am trying to figure out what it's missing what I don't find the way to do it.
Here is the link to codepen: https://codepen.io/felixgonzalo/pen/poJoXRW
My code is:
<div class="main-wrapper">
<div class="video-container">
<video id="video" class="video" controls class="border" controls="false" muted loop>
<source src="https://www.errorerror.studio/wp-content/uploads/2020/01/ee.st-honesty-clip-00.mp4" preload="auto" type="video/mp4" autoplay />
</video>
<div class="overlay"></div>
</div>
<div class="video-container">
<video id="video-2" class="video" controls class="border" controls="false" muted loop>
<source src="https://www.errorerror.studio/wp-content/uploads/2020/01/ee.st-honesty-clip-00.mp4" preload="auto" type="video/mp4" autoplay />
</video>
<div class="overlay"></div>
</div>
</div>
jQuery
$('.video').prop('currentTime', 0)
function Play() {
$('.video').get(0).play();
}
function Stop() {
$('.video').prop('currentTime', 0).get(0).pause();
}
$(document).ready(function(){
$('.video-container').mouseenter(function(){
$('.overlay', this).addClass("hide")
Play();
}).mouseleave(function(){
$('.overlay', this).removeClass("hide")
Stop();
});
});
I also tried to make it in JS but didn't work out:
var container = document.querySelector('.video-container');
container.addEventListener('mouseleave', function() {
this.querySelector('.overlay').classList.remove('hide');
Stop();
});
container.addEventListener('mouseenter', function() {
this.querySelector('.overlay').classList.add('hide');
Play()
});
Really appreciate any help
Your function play gets only the first video because you specified the 0 index. You need to pass the current video index you're hovering to trigger the playback.
EDIT: Working code.
I made your functions taking an argument, which I'm setting to the first video element children of the element triggering the mouse events.
$('.video').prop('currentTime', 0)
$(document).ready(function() {
$('.video-container').mouseenter(function() {
$('.overlay', this).addClass("hide")
$(this).children('.video')[0].play();
}).mouseleave(function() {
$('.overlay', this).removeClass("hide")
$($(this).children('.video')[0]).prop('currentTime', 0)
$(this).children('.video')[0].pause();
});
});
I found this similar question here, however the answer did not work in my case.
My JsFiddle: http://jsfiddle.net/leongaban/yvne6fnt/
HTML
<div style="position: fixed; top: 0; width: 100%; height: 100%; z-index: -1;">
<video id="hero_video" controls="" autoplay="autoplay" preload poster="http://media.w3.org/2010/05/sintel/poster.png" style="width:100%; height:100%">
<source id="mp4" src="http://leongaban.com/v6/videos/clouds.mp4" type="video/mp4">
<source id="webm" src="http://leongaban.com/v6/videos/clouds.webm" type="video/webm">
<source id="ogv" src="http://leongaban.com/v6/videos/clouds.ogv" type="video/ogg">
<p>Your user agent does not support the HTML5 Video element.</p>
</video>
JS
$("#hero_video").bind('stop', function(e) {
console.log('stopped');
alert('stopped');
}, true);
/*
$("video").bind('stop', function(e) {
console.log('stopped');
alert('stopped');
}, true);
*/
This works if you remove the 3rd argument from your function:
$("#hero_video").bind('stop', function(e) {
console.log('stopped');
alert('stopped');
});
Notice that this will only be triggered at the beginning and of the video. If you want to also trigger an event on pause, you have to also include the pause event:
$("#hero_video").bind('stop pause', function(e) {
console.log('stopped');
alert('stopped');
});
JsFiddle: http://jsfiddle.net/yvne6fnt/8/
Not sure why this works though, since the default for that argument is true. http://api.jquery.com/bind/
i am working on a site that has a video as soon as we enter the site.
The problem is it just ends and I want to replace it with an image after it ends.
Is there a way I can redirect it within the same container.?
<video id="video_background" preload="auto" volume="5" autoplay="1"><!--or turn on loop="loop"-->
<source src="videos/trailer.webm" type="video/webm">
<source src="videos/trailer.mp4" type="video/mp4">
<source src="videos/trailer.ogv" type="video/ogg ogv">
</video>
You'll have to use JavaScript to detect video end but it's easy to implement:
var video = document.getElementById('video_background');
video.addEventListener('ended', function() {
// show image here
}, false);
I would recommend to target a parent container which has a pre-loaded image hidden and which you toggle to when the event kicks in (obviously also hiding the video element).
You could also add the image dynamically but be aware of that you will have a delay while the image is loading.
You need to wrap your video tag in a div container. Try the following code:
CSS:
#wrapper{
width:640px;
height:360px;
background:#000;
}
#image_background{
display:none;
}
HTML:
<div id="wrapper">
<video id="video_background" preload="auto" volume="5" autoplay="1" width="100%" height="100%">
<source src="videos/trailer.webm" type="video/webm" />
<source src="videos/trailer.mp4" type="video/mp4" />
<source src="videos/trailer.ogv" type="video/ogg ogv" />
</video>
<img id="image_background" src="yourImage.jpg" width="100%" height="100%" />
</div>
JS:
var video = document.getElementById('video_background');
var wrapper = document.getElementById('wrapper');
var image = document.getElementById('image_background');
video.addEventListener('ended', function() {
video.style.display = 'none';
image.style.display = 'inline';
}, false);
EDIT: how do i smooth-en the transition fade it in or something?
I would use jQuery for this as it is built with such functionalities.
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
var video = $('#video_background');
var image = $('#image_background');
video.on('ended', function() {
$(this).fadeOut('200',function(){//$(this) refers to video
image.fadeIn('200');
});
});
</script>