I have several videos on my site that have the same class.
I want to play only one video when hovering over it. As soon as I removed the hover, the video was paused with a delay of 1 second.
I learned how to start a video and pause it. But as soon as I add setTimeout I get an error:
Uncaught TypeError: Cannot read properties of undefined (reading 'pause')
Below I am attaching the html code of my solution:
<a href="#" >
<video playsinline="true" loop="" preload="metadata" src="https://giant.gfycat.com/VerifiableTerrificHind.mp4"></video>
</a>
<a href="#" >
<video playsinline="true" loop="" preload="metadata" src="https://giant.gfycat.com/VerifiableTerrificHind.mp4"></video>
</a>
<a href="#" >
<video playsinline="true" loop="" preload="metadata" src="https://giant.gfycat.com/VerifiableTerrificHind.mp4"></video>
</a>
Also I am attaching the html code of my solution:
var figure = $(".cases__item").hover( hoverVideo, hideVideo );
function hoverVideo(e) {
$('.cases__item-video', this).get(0).play();
}
function hideVideo(e) {
setTimeout(function (){
$('.cases__item-video', this).get(0).pause();
}, 1000);
}
I also add working jsfiddle with my code: https://jsfiddle.net/v7certb6/1/
Please help me to resolve the video pause issue after one second.
I will be very grateful for any help.
CodePudding user response:
The issue is because this in the setTimeout() function handler refers to that function, not to the element reference provided in the invocation of the outer hoverVideo() or hideVideo() functions.
To fix this issue create a variable in the outer scope to retain the reference to this which you use within the setTimeout():
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<a href="#" >
<video playsinline="true" loop="" preload="metadata" src="https://giant.gfycat.com/VerifiableTerrificHind.mp4"></video>
</a>
<a href="#" >
<video playsinline="true" loop="" preload="metadata" src="https://giant.gfycat.com/VerifiableTerrificHind.mp4"></video>
</a>
<a href="#" >
<video playsinline="true" loop="" preload="metadata" src="https://giant.gfycat.com/VerifiableTerrificHind.mp4"></video>
</a>
var figure = $(".cases__item").hover(hoverVideo, hideVideo);
function hoverVideo(e) {
let _this = this;
$('.cases__item-video', _this).get(0).play();
}
function hideVideo(e) {
let _this = this;
setTimeout(function() {
$('.cases__item-video', _this).get(0).pause();
}, 1000);
}
Example Fiddle - note the example is in a fiddle as the cross-site content has issues when played on the main SO site.
As a side note, the JS can be reduced to the following, which has the exact same behaviour just using arrow functions:
$(".cases__item").hover(
e => e.currentTarget.querySelector('.cases__item-video').play(),
e => setTimeout(() => e.currentTarget.querySelector('.cases__item-video').pause(), 1000));
