Youtube iframe API 事件在后期添加播放器时未触发
Youtube iframe API events not triggering when player is added at later stage
我有一个应用程序,当用户请求特定视频时,我会在某个时间点注入 youtube iframe 播放器(完整的 iframe html 片段)。这可能会发生,例如加载应用程序后 30 秒或任何时间点,只是加载应用程序后不正确。
这似乎是 youtube API 的问题。在我下面的代码示例中,您可以看到该示例不起作用,因为我在 1 秒后添加了 iframe 播放器。当您将超时从 1000 降低到仅 1 毫秒时,代码工作正常。
由于该测试,我发现 YT 事件没有触发,因为我的播放器是在应用程序加载一段时间后被注入的。
有没有办法在玩家未立即添加到 dom 时触发事件?或者有人可以解释为什么事件仅在播放器立即添加到页面时才起作用(即使元素本身是在脚本之后添加的)
https://jsbin.com/vuhibelabi/1/edit?html,output
<div id="test" style="display:none;"></div>
<script type="text/javascript">
var tag = document.createElement('script');
tag.id = 'iframe-demo';
tag.src = 'https://www.youtube.com/iframe_api';
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('existing-iframe-example', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
document.getElementById('existing-iframe-example').style.borderColor = '#FF6D00';
}
function changeBorderColor(playerStatus) {
var color;
if (playerStatus == -1) {
color = "#37474F"; // unstarted = gray
} else if (playerStatus == 0) {
color = "#FFFF00"; // ended = yellow
} else if (playerStatus == 1) {
color = "#33691E"; // playing = green
} else if (playerStatus == 2) {
color = "#DD2C00"; // paused = red
} else if (playerStatus == 3) {
color = "#AA00FF"; // buffering = purple
} else if (playerStatus == 5) {
color = "#FF6DOO"; // video cued = orange
}
if (color) {
document.getElementById('existing-iframe-example').style.borderColor = color;
}
}
function onPlayerStateChange(event) {
changeBorderColor(event.data);
}
function go(){
var player = `<iframe id="existing-iframe-example"
width="640" height="360"
src="https://www.youtube.com/embed/M7lc1UVf-VE?enablejsapi=1"
frameborder="0"
style="border: solid 4px #37474F"
></iframe>`;
document.querySelector("#test").innerHTML = player;
document.querySelector("#test").style.display = "block";
}
setTimeout(function(){
go();
}, 1000)
</script>
对于处于相同情况的任何人,我已经切换到使用 JS-based solution 而不是注入完整的 iframe,这似乎工作正常。
我有一个应用程序,当用户请求特定视频时,我会在某个时间点注入 youtube iframe 播放器(完整的 iframe html 片段)。这可能会发生,例如加载应用程序后 30 秒或任何时间点,只是加载应用程序后不正确。
这似乎是 youtube API 的问题。在我下面的代码示例中,您可以看到该示例不起作用,因为我在 1 秒后添加了 iframe 播放器。当您将超时从 1000 降低到仅 1 毫秒时,代码工作正常。
由于该测试,我发现 YT 事件没有触发,因为我的播放器是在应用程序加载一段时间后被注入的。
有没有办法在玩家未立即添加到 dom 时触发事件?或者有人可以解释为什么事件仅在播放器立即添加到页面时才起作用(即使元素本身是在脚本之后添加的)
https://jsbin.com/vuhibelabi/1/edit?html,output
<div id="test" style="display:none;"></div>
<script type="text/javascript">
var tag = document.createElement('script');
tag.id = 'iframe-demo';
tag.src = 'https://www.youtube.com/iframe_api';
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('existing-iframe-example', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
document.getElementById('existing-iframe-example').style.borderColor = '#FF6D00';
}
function changeBorderColor(playerStatus) {
var color;
if (playerStatus == -1) {
color = "#37474F"; // unstarted = gray
} else if (playerStatus == 0) {
color = "#FFFF00"; // ended = yellow
} else if (playerStatus == 1) {
color = "#33691E"; // playing = green
} else if (playerStatus == 2) {
color = "#DD2C00"; // paused = red
} else if (playerStatus == 3) {
color = "#AA00FF"; // buffering = purple
} else if (playerStatus == 5) {
color = "#FF6DOO"; // video cued = orange
}
if (color) {
document.getElementById('existing-iframe-example').style.borderColor = color;
}
}
function onPlayerStateChange(event) {
changeBorderColor(event.data);
}
function go(){
var player = `<iframe id="existing-iframe-example"
width="640" height="360"
src="https://www.youtube.com/embed/M7lc1UVf-VE?enablejsapi=1"
frameborder="0"
style="border: solid 4px #37474F"
></iframe>`;
document.querySelector("#test").innerHTML = player;
document.querySelector("#test").style.display = "block";
}
setTimeout(function(){
go();
}, 1000)
</script>
对于处于相同情况的任何人,我已经切换到使用 JS-based solution 而不是注入完整的 iframe,这似乎工作正常。