Issue
Below is a snippet of HTML code that contains some videos. The videos have controls but you have to click on them so that it starts playing. I don't like clicking. Hence, I want the video that is on the screen to start playing automatically without the need for the user to click on it. The video must stop playing as soon as the user scrolls upwards or downwards, which causes the new video that has appeared on the screen to start to play. When the user scrolls away, the video must stop and the next video (that has replaced the place of the old video) must start to play. This is what I want. If you are not understanding what I mean, just open YouTube on your mobile and scroll down the home page for some time. You will see that the videos automatically start to play and stop as you scroll their home page. This same effect has to be created in the snippet given below.
NOTE: There are about 3 videos on the screen at the same time. All three of them must not start to play together. The video at the center or which occupies the most space on the screen should start playing automatically (just like YouTube mobile app)
This feature does not work on the YouTube website for PCs. There, the only video that starts playing is the video in which the user hovers and it stops doing so as soon as the user moves the Mouse pointer away and the thumbnail is displayed again. (I might add thumbnails to this videos also using poster attribute)
This is the snippet
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
<div class="row">
<div class="col-12 col-md-6 col-lg-4 col-xl-3">
<video src="/Main/images/squirrel_on_a_wood (1080p).mp4" controls playsinline></video>
</div>
<div class="col-12 col-md-6 col-lg-4 col-xl-3">
<video src="/Main/images/squirrel_on_a_wood (1080p).mp4" controls playsinline></video>
</div>
<div class="col-12 col-md-6 col-lg-4 col-xl-3">
<video src="/Main/images/squirrel_on_a_wood (1080p).mp4" controls playsinline></video>
</div>
<div class="col-12 col-md-6 col-lg-4 col-xl-3">
<video src="/Main/images/squirrel_on_a_wood (1080p).mp4" controls playsinline></video>
</div>
<div class="col-12 col-md-6 col-lg-4 col-xl-3">
<video src="/Main/images/squirrel_on_a_wood (1080p).mp4" controls playsinline></video>
</div>
<div class="col-12 col-md-6 col-lg-4 col-xl-3">
<video src="/Main/images/squirrel_on_a_wood (1080p).mp4" controls playsinline></video>
</div>
<div class="col-12 col-md-6 col-lg-4 col-xl-3">
<video src="/Main/images/squirrel_on_a_wood (1080p).mp4" controls playsinline></video>
</div>
</div>
<style>
video{
width: 90%;
margin: 5%;
}
</style>
Saying all this, my problem is that though I know HTML and CSS, my knowledge of JavaScript is not too good to do all of this. Please do this for me and also explain it to me that how it works so that I can use it on my main project and increase my knowledge about web developing. Or, if you will not do this, at least give me a detailed prompt so that I can ask ChatGPT or any other chatbot how to do it if it is not possible for you to help.
Solution
This is a quite complex issue, so we need to start by splitting it into a couple of steps:
Step 1 - run JS
Run your JavaScript code after the HTML is parsed, so that JS "sees" your HTML contents
If you want to have the JS code in the same file as HTML, you'll need to put the <script> tag with the code at the very end of the HTML file (as the last element inside the body).
If your JS is in a separate file, you should use the defer attribute of the script tag:
<script src="/path/to/file.js" defer />
This can be put anywhere in your HTML, not necessarily in the end. The defer attribute will cause your code to be run after the HTML is parsed.
Step 2 - detect entering/leaving viewport
The next step would be to set up some kind of listener, so that you know when your video elements enter or leave the page. The most efficient way to do that would be to use the IntersectionObserver Web API. In the documentation you can see a couple of examples of using this API.
You will want to set up an observer for every video element in your HTML, so you would do it like this:
const videos = document.querySelectorAll('video');
for (const video of videos) {
// set up an observer here
}
In your case I would recommend setting the threshold option of the observer to 1.0 so that it's only triggered when the element is completely in viewport, not just partially.
Inside the observer callback, you can use the isIntersecting field of the entry object to check if the element has just entered or left the viewport. Example:
function observerCallback(entries) {
const isVisible = entries[0].isIntersecting;
if (isVisible) {
// the element is visible, you can play the video
}
else {
// the element is not visible, you can pause the video
}
}
Step 3 - playing or pausing the video
In order to play or pause the video, you can use the play and pause methods of the video element.
video.play();
video.pause();
Further improvements
- In order to start playing the video when it's closer to the middle of the viewport (and not immediately when it enters the viewport) you can use the
rootMarginoption of the IntersectionObserver - In order to only have one video playing at once, you can keep track of the currently played video in a variable, like this:
// place this variable somewhere so that it's accessible to the function below // and its value is not lost let currentlyPlayingVideo; // run this function in the observer callback function playAnotherVideo(newVideo) { if (currentlyPlayingVideo !== undefined) currentlyPlayingVideo.pause(); newVideo.play(); currentlyPlayingVideo = newVideo; }
Answered By - norbnik
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.