I want to lazy load the youtube video with iframe API. ie. load only the poster image in the beginning and when user clicks on it then only load the actual image and its content.
I want to lazy load the youtube video with iframe API. ie. load only the poster image in the beginning and when user clicks on it then only load the actual image and its content.
Share Improve this question asked Jun 16, 2016 at 10:25 madhuhcmadhuhc 1381 gold badge2 silver badges8 bronze badges 3- 3 Right now I want some food but I have to hunt for it first. e.g. provide some code of things you've tried. – Tim Vermaelen Commented Jun 16, 2016 at 10:36
- Do you mean something like this? newmediacampaigns.com/blog/… – Jaapze Commented Jun 16, 2016 at 10:56
- I was able to get it working answer is in comment section. – madhuhc Commented Jun 20, 2016 at 18:52
7 Answers
Reset to default 8Most of this is taken from the getting started section on the youtube page.
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<script>
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
This example loads the video when it is ready.
So we change it up a bit to add in a placeholder image and on click hide the image and play the video.
Wrap the tag (step 2) in function
function loadYT() {
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
Add an image Check this question for more details on sizes.
<div id="placeholder">
<img src="http://img.youtube.com/vi/M7lc1UVf-VE/sddefault.jpg" />
</div>
Then on click hide the placeholder image and load the player
document.getElementById("placeholder").addEventListener("click", function(){
this.style.display = 'none';
loadYT()
});
Final result can be seen below.
<div id="placeholder">
<img src="http://img.youtube.com/vi/M7lc1UVf-VE/sddefault.jpg" />
</div>
</div>
<div id="player"></div>
<script>
document.getElementById("placeholder").addEventListener("click", function(){
this.style.display = 'none';
loadYT()
});
// 2. This code loads the IFrame Player API code asynchronously.
function loadYT() {
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
<iframe loading="lazy"
This HTML feature allows lazy loading YouTube iframe
embeds only when the user scrolls over them, without any extra JavaScript (the YouTube video is of course automatically loaded via JavaScript in the iframe
however).
Here is a working jsfiddle: https://jsfiddle.net/cirosantilli/3p0tk5nc/1/ that I have tested on Chromium 81. You can see on the developer tools "network" tab that the frames only load when you scroll over them.
It does not work on Stack Overflow snippets for some reason however because YouTube videos appear to not work on Stack Overflow in general, not because of loading="lazy"
in particular.
More details at: lazy load iframe (delay src http call) with jquery
Why load the videos on click, and not just when the user sees them? Use jQuery.Lazy and you have nothing more to do. :)
Add the Plugin to your Page: (you will need jQuery or Zepto as well)
<script type="text/javascript" src="//cdn.jsdelivr.net/jquery.lazy/1.7.1/jquery.lazy.min.js"></script>
<script type="text/javascript" src="//cdn.jsdelivr.net/jquery.lazy/1.7.1/plugins/jquery.lazy.youtube.min.js"></script>
Prepare your iFrames: (note the data-loader
and data-src
attributes)
<iframe data-loader="youtube" data-src="1AYGnw6MwFM" width="560" height="315"></iframe>
And start using Lazy:
$(function() {
$("iframe[data-src]").Lazy();
});
That's it! The iFrames will be loaded whenever the user reaches them by scrolling. More inormations here.
you can initially hide the iframe and use intersection obesrver api to load the youtube video when it is in the visible screen
let options = {
root: document.querySelector("#youtubevideo"),
rootMargin: "0px",
threshold: 1.0,
};
let observer = new IntersectionObserver(()=>{
// actual logic to show youtube video
}, options);
How about this?
HTML
<div class="wrapper">
<ul>
<li><a title="video 1" data-video="http://www.youtube.com/embed/X0DeIqJm4vM">Motherlover</a></li>
<li><a title="video 2" data-video="http://www.youtube.com/embed/GI6CfKcMhjY">Jack Sparrow</a></li>
<li><a title="video 3" data-video="http://www.youtube.com/embed/TcK0MYgnHjo">Ras trent</a></li>
<li><a title="video 4" data-video="http://www.youtube.com/embed/8yvEYKRF5IA">Boombox</a></li>
<li><a title="video 5" data-video="http://www.youtube.com/embed/6_W_xLWtNa0">Shy Ronnie 2</a></li>
</ul>
<iframe id="videoArea" width="350" height="250" src="http://www.youtube.com/embed/X0DeIqJm4vM" frameborder="0" allowfullscreen></iframe>
</div>
JS
var initVideos = function() {
var videoArea = $("#videoArea"),
divs = $("ul li a"); // or some other data format
// bind your hover event to the divs
divs.click(function(ev) {
ev.preventDefault();
videoArea.prop("src", $(this).data('video'));
divs.removeClass("active");
$(this).addClass("active");
});
};
// once the DOM is ready
$(function() {
initVideos();
});
DEMO
I just lazy load the thumbnail and only load the real video if the visitor is hovering the thumbnail. For Privacy reasons you can also make him click a confirmation before loading the video from youtube.
<?php $youtubevideo="Video ID1"; $youtubezaehler=$youtubezaehler+1;?>
<br>
<div align="center" class="video-container" onmouseover="video<?php echo($youtubezaehler);?>()">
<div style="position:relative;">
<a href="javascript:video<?php echo($youtubezaehler);?>()"><img loading="lazy" id="vorschaubild<?php echo($youtubezaehler);?>" class="" src="https://img.youtube.com/vi/<?php echo($youtubevideo);?>/<?php echo $youtube_aufloesung; ?>" width="100%" alt="Lade..."></a>
<div id="play<?php echo($youtubezaehler);?>" style="position:absolute; top:30%; left:46%; width:10%;"><img src="play.gif" alt="Play" style="width:100%;"></div>
</div>
<script type="text/javascript">
<!--
//JavaScript zum DSGVO konformem und Ladezeitoptimierten Einbinden der Youtube Videos erst bei Nutzung
function video<?php echo($youtubezaehler);?>() {
if(document.getElementById("vorschaubild<?php echo($youtubezaehler);?>").style.visibility=="hidden") return false; //Damit das Video nicht beim abspielen versehntlich neu geladen wird
document.getElementById("vorschaubild<?php echo($youtubezaehler);?>").height = "1px";
document.getElementById("vorschaubild<?php echo($youtubezaehler);?>").style.visibility="hidden";
document.getElementById("play<?php echo($youtubezaehler);?>").style.visibility="hidden";
document.getElementById("video<?php echo($youtubezaehler);?>").src = "https://www.youtube-nocookie.com/embed/<?php echo($youtubevideo);?>?rel=0";
}
// -->
</script>
<iframe title="Video" id="video<?php echo($youtubezaehler);?>" src="" frameborder="0" allowfullscreen></iframe>
</div>
Finally it worked, below code is in angularJS.
HTML
<div data-ng-repeat="video in videoIds track by $index">
<div id="uniQueId" ng-click="playVideo(video, 'player' + $index)">
<div class="video-play-button"></div>
</div>
</div>
JS
$scope.playVideo = function(videoId, id) {
$scope.players[id] = new YT.Player(id, {
videoId: videoId,
width: '400',
height: '300',
playerVars: { 'autoplay': 1 },
events: {
'onStateChange': $scope.onPlayerStateChange
}
});
};