23.10.2021, 12:44
|
|
Аспирант
|
|
Регистрация: 23.11.2013
Сообщений: 96
|
|
iframe загрузка видео youtube
Для оптимизации скорости загрузки страницы загружаю youtube-видео после того, как контейнер под видео будет в области видимости, до этого момента отображаю просто картинку
Необходимо убирать картинку, когда видео будет полностью загружено загружено.
Но когда вешаю onload на iframe, он срабатывает дважды, в момент когда видео ещё не готово к проигрыванию. Как это исправить, чтоб картинка убиралась после загрузки и готовности видео к воспоизведению?
<div class="youtube-video-lazy" data-video="5qap5aO4i9A" style="width: 480px; height: 320px; position: absolute; top: 0px; left: 0px; border: none;">
<img src="" alt="video">
<button style="border: none; background: transparent; cursor: pointer; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);">
<svg width="68" height="48" viewBox="0 0 68 48">
<path class="video-play-shape" style="fill: #212121; fill-opacity: 0.8;" d="M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z">
</path>
<path class="video-play-icon" style="fill: #ffffff;" d="M 45,24 27,14 27,34"></path>
</svg>
</button>
<iframe style="width: 100%; height: 100%; display: block; object-fit: cover; border: none;" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture;" allowfullscreen=""></iframe>
</div>
<script>
function loadYoutubeElem(el) {
let videoId = el.getAttribute('data-video');
let iframe = el.querySelector('iframe');
let query = '?rel=0&showinfo=0&autoplay=1';
iframe.setAttribute('src', 'https://www.youtube.com/embed/' + videoId + query);
iframe.onload = e => {
// срабатывает два раза,
el.querySelector('img').remove();
el.querySelector('button').remove();
}
}
function visibleYoutubeElem() {
let elem = document.querySelectorAll('.youtube-video-lazy')[0];
let targetPosition = {
top: window.pageYOffset + elem.getBoundingClientRect().top,
left: window.pageXOffset + elem.getBoundingClientRect().left,
right: window.pageXOffset + elem.getBoundingClientRect().right,
bottom: window.pageYOffset + elem.getBoundingClientRect().bottom
};
let windowPosition = {
top: window.pageYOffset,
left: window.pageXOffset,
right: window.pageXOffset + document.documentElement.clientWidth,
bottom: window.pageYOffset + document.documentElement.clientHeight
};
if (targetPosition.bottom > windowPosition.top &&
targetPosition.top < windowPosition.bottom &&
targetPosition.right > windowPosition.left &&
targetPosition.left < windowPosition.right) {
loadYoutubeElem(elem);
window.removeEventListener('scroll', visibleYoutubeElem);
};
}
window.addEventListener('scroll', visibleYoutubeElem);
document.querySelectorAll('.youtube-video-lazy').forEach(el => {
let videoId = el.getAttribute('data-video');
let img = el.querySelector('img');
let youtubeImgSrc = 'https://i.ytimg.com/vi/' + videoId + '/sddefault.jpg';
let styles = 'width: 100%; height: 100%; display: block; object-fit: cover; border: none;';
img.setAttribute('style', styles);
img.setAttribute('src', youtubeImgSrc);
});
</script>
|
|
23.10.2021, 12:47
|
|
Аспирант
|
|
Регистрация: 23.11.2013
Сообщений: 96
|
|
Или, может быть посоветуете способ загрузки видео по клику?
Это гораздо лучше, но по клику не корректно работает на мобильных устройствах. Там запрещено автовоспроизведение, и нужно кликать дважды: первый раз, чтоб отобразить видео, второй раз, чтоб его воспроизвести
|
|
23.10.2021, 15:33
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,127
|
|
youtube ленивая загрузка
lgick,
<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<style type="text/css">
.youtube-video-lazy {
width: 480px;
height: 320px;
position: relative;
top: 0px;
left: 0px;
border: none;
}
iframe.youtube-video-lazy {
transform: scale(0.9);
opacity: 0;
transition: transform .5s, opacity 1.5s;
}
iframe.youtube-video-lazy.ready {
opacity: 1;
transform: scale(1);
}
.youtube-video-lazy>img {
width: 100%;
height: 100%;
display: block;
object-fit: cover;
border: none;
}
.youtube-video-lazy>button {
border: none;
background: transparent;
cursor: pointer;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
p {
height: 1000px;
}
</style>
</head>
<body>
<p></p>
<div class="youtube-video-lazy" data-video="5qap5aO4i9A">
<img src="" alt="video">
<button>
<svg width="68" height="48" viewBox="0 0 68 48">
<path class="video-play-shape" style="fill: #212121; fill-opacity: 0.8;" d="M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z">
</path>
<path class="video-play-icon" style="fill: #ffffff;" d="M 45,24 27,14 27,34"></path>
</svg>
</button>
</div>
<p></p>
<div class="youtube-video-lazy" data-video="xwmDe0OhhPs">
<img src="" alt="video">
<button>
<svg width="68" height="48" viewBox="0 0 68 48">
<path class="video-play-shape" style="fill: #212121; fill-opacity: 0.8;" d="M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z">
</path>
<path class="video-play-icon" style="fill: #ffffff;" d="M 45,24 27,14 27,34"></path>
</svg>
</button>
</div>
<p></p>
<script>
let tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
let firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
function onYouTubeIframeAPIReady() {
let lazyYoutube = divs =>
divs.forEach(el => {
if (el.intersectionRatio > 0.8) {
let div = el.target;
observer.unobserve(div);
div.visibleYoutubeElem()
}
});
let observer = new IntersectionObserver(lazyYoutube, {
rootMargin: "0px",
threshold: [.8]
});
let youtube = document.querySelectorAll('.youtube-video-lazy');
youtube.forEach(div => {
let videoId = div.dataset.video;
let img = div.querySelector('img');
let youtubeImgSrc = `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`;
img.src = youtubeImgSrc;
observer.observe(div);
const onPlayerReady = function(q) {
q.target.h.classList.add('ready')
}
div.visibleYoutubeElem = _ => {
new YT.Player(div, {
height: '320',
width: '480',
videoId,
events: {
'onReady': onPlayerReady
}
});
}
})
}
</script>
</body>
</html>
Последний раз редактировалось рони, 23.10.2021 в 16:10.
|
|
23.10.2021, 19:58
|
|
Аспирант
|
|
Регистрация: 23.11.2013
Сообщений: 96
|
|
рони,
Не знал о IntersectionObserver, спасибо большое!
|
|
|
|