Reputation: 23
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="#" class="cases__item">
<video class="cases__item-video" playsinline="true" loop="" preload="metadata" src="https://giant.gfycat.com/VerifiableTerrificHind.mp4"></video>
</a>
<a href="#" class="cases__item">
<video class="cases__item-video" playsinline="true" loop="" preload="metadata" src="https://giant.gfycat.com/VerifiableTerrificHind.mp4"></video>
</a>
<a href="#" class="cases__item">
<video class="cases__item-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.
Upvotes: 2
Views: 517
Reputation: 337560
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="#" class="cases__item">
<video class="cases__item-video" playsinline="true" loop="" preload="metadata" src="https://giant.gfycat.com/VerifiableTerrificHind.mp4"></video>
</a>
<a href="#" class="cases__item">
<video class="cases__item-video" playsinline="true" loop="" preload="metadata" src="https://giant.gfycat.com/VerifiableTerrificHind.mp4"></video>
</a>
<a href="#" class="cases__item">
<video class="cases__item-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));
Upvotes: 1