Ich kämpfe schon seit geraumer Zeit mit dem Youtube-iframe-API. Irgendwie wird die Methode onYouTubeIframeAPIReady
nicht immer ausgelöst.
Aus den Symptomen scheint es ein Ladeproblem zu sein. Im Inspector werden keine Fehler angezeigt.
Hier ist mein Code:
<div id="player"></div>
<script>
videoId = 'someVideoId';
var tag = document.createElement('script');
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
</script>
(Aufruf am Ende der Seite. Ich habe versucht, den Code direkt nach dem obigen Skript zu platzieren, und das Ergebnis war dasselbe.)
var isReady = false
, player
, poster
, video;
$(function () {
$('.js-play').click(function (e) {
e.preventDefault();
interval = setInterval(videoLoaded, 100);
});
});
function onYouTubeIframeAPIReady() {
console.log(videoId)
player = new YT.Player('player', {
height: '445',
width: '810',
videoId: videoId,
events: {
'onReady': onPlayerReady//,
//'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
isReady = true;
console.log("youtube says play")
}
function videoLoaded (){
if (isReady) {
console.log("ready and play")
poster.hide();
video.show();
$('body').trigger('fluidvideos');
player.playVideo();
clearInterval(interval);
}
}
Das Problem ist, dass manchmal nichts vom console.log
gedruckt wird und nichts passiert.
Auf Mobiltelefonen geschieht dies ständig. Irgendwelche Ideen?
Es ist kein Timeout-Problem, und Sie sollten diese Funktion nicht manuell auslösen müssen.
Stellen Sie sicher, dass Ihre onYouTubeIframeAPIReady
-Funktion auf globaler Ebene verfügbar ist und nicht in einer anderen Funktion verschachtelt (ausgeblendet) wird.
Sie können es immer an das Fensterobjekt anhängen, um sicherzustellen, dass es global aufgerufen wird. Dies ist hilfreich, wenn Ihr Code AMD verwendet.
window.onYouTubeIframeAPIReady = function() {}
Wenn Sie eine Funktion in eine Funktion einfügen müssen, ist eine mögliche Lösung .__ anstelle von:
function onYouTubeIframeAPIReady() {
// func body...
}
sie können es so erklären:
window.onYouTubeIframeAPIReady = function() {
// func body...
}
Stellen Sie in diesem Fall sicher, dass Sie das bestimmte Skript nach der Deklaration in den dom einfügen (der Aufruf von insertBefore()
, was jetzt in Ihrem Fall im globalen Bereich liegt)
Wenn Sie den IFrame Player-API-Code asynchron wie folgt laden:
<script>
var tag = document.createElement('script');
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
</script>
und Sie laden den Skriptcode auch so:
<script src="http://www.youtube.com/player_api"></script>
dann wird die Funktion onYouTubeIframeAPIReady
nicht aufgerufen, da derselbe Code zweimal geladen wird (die Funktion wird nur einmal aufgerufen, wenn das API vollständig geladen ist).
Verwenden Sie also eine der Möglichkeiten, die Ihren Bedürfnissen entspricht.
Nachdem ich dies erneut besprochen hatte, fand ich eine funktionierende Lösung für mich, wenn ich webpack verwende (oder ich gehe von einem anderen commongJS-Modulsystem aus), oder wenn Sie feststellen, dass die Youtube-API vor Ihrer eigenen JS-Datei bereit ist, ein Intervall zu verwenden war - bis Youtube ein solches bereitstellt Form des Versprechensrückrufs:
var checkYT = setInterval(function () {
if(YT.loaded){
//...setup video here using YT.Player()
clearInterval(checkYT);
}
}, 100);
Dies schien in meinem Fall der fehleranfälligste zu sein.
Stellen Sie sicher, dass Sie die Seite testen, indem Sie sie tatsächlich im Web bereitstellen und nicht nur lokal laden. Das Verhalten der YouTube-iFrame-API ist inkonsistent/nicht deterministisch
Ich hatte ein ähnliches Problem. In meinem Fall wurde onYouTubeIframeAPIReady so schnell aufgerufen, dass die tatsächliche Implementierung nicht für den richtigen Aufruf bereit war. Nach dem Aufruf von youtube player_api habe ich also eine einfache Implementierung mit einer var zur Verifizierung von onYouTubeIframeAPIReady hinzugefügt:
<script src="http://www.youtube.com/player_api"></script>
<script>
var playerReady = false
window.onYouTubeIframeAPIReady = function() { //simple implementation
playerReady = true;
}
</script>
</header>
.
.
.
<body>
<script>
window.onYouTubeIframeAPIReady = function() { //real and fully implemented
var player; // ... and so on ...
}
if(playerReady) { onYouTubeIframeAPIReady(); console.log("force to call again") }
</script>
Ich habe das eigentlich zum faulen Laden des Youtube-Players gemacht. Kommt mir kugelsicher vor.
window.videoApiLoaded = [];
window.videoApiLoaded.youtube = false;
function loadYoutubeVideo(videoId) {
window.onYouTubeIframeAPIReady = function() { document.dispatchEvent(new CustomEvent('onYouTubeIframeAPIReady', {})) };
if(window.videoApiLoaded.youtube == false) {
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
window.videoApiLoaded.youtube = true;
}
var player;
document.addEventListener('onYouTubeIframeAPIReady', function (e) {
player = new YT.Player('player', {
height: '400',
width: '600',
videoId: videoId,
events: {
'onStateChange': onYtStateChange
}
});
}, false);
}