在我的一个模态中,我想显示一个YouTube视频。哪一个(哪个ID)取决于用于打开模型的按钮。
<button class='yt-play' data-yt='xxxxxx'>Play video</button>
在我的javascript文件中,我使用YT player-api生成iframe;我跟着Getting started on google developers。
所以在模态中我添加了一个<div id='player'></div>
,这是我包含的javascript:
var tag = document.createElement('script');
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('player', {
videoId: '5ulO97zuVF0', //- just a temporary id
});
}
// on document ready do some jQuery things,
// like adding an event handler to the button.
$(document).ready(function (){
$('.yt-play').click(function(ev){
ev.preventDefault();
var videoid = $(this).data('yt');
player.loadVideoById(videoid);
$('#yt-player').modal('show');
player.playVideo();
});
});
yt-play上的点击处理程序应该按照所述here in the documentation的方式通过player.loadVideoById()加载视频。
但不知怎的,我收到了一个javascript错误:TypeError: player.loadVideoById is not a function
如果我将玩家对象转储到控制台中,我会得到一个漂亮的玩家对象;其中包含loadVideoById函数。至少它看起来像:
未加载新视频的原因是什么?
答案 0 :(得分:1)
可能是因为&#34; loadVideoById&#34;还没有。
您必须使用事件对象构建YT.Player对象,并包含&#34; onReady&#34;事件回调。
然后在你的&#34; onReady&#34;绑定按钮点击事件的回调函数。
function onPlayerReady() {
$('.yt-play').click(function(ev){
ev.preventDefault();
var videoid = $(this).data('yt');
// player.loadVideoByID is now available as a function
player.loadVideoById(videoid);
$('#yt-player').modal('show');
player.playVideo();
});
}
player = new YT.Player('player', {
videoId: '5ulO97zuVF0', //- just a temporary id,
events:{
“onReady”: onPlayerReady
}
});
请参阅文档中的事件部分了解更多信息:
https://developers.google.com/youtube/iframe_api_reference#Events
答案 1 :(得分:0)
答案 2 :(得分:0)
代码:
<script>
// load API
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// define player
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '360',
width: '640'
});
}
$(function () {
// load video and add event listeners
function loadVideo(id, start, end) {
// check if player is defined
if ((typeof player !== "undefined")) {
// listener for player state change
player.addEventListener('onStateChange', function (event) {
if (event.data == YT.PlayerState.ENDED) {
// do something
}
});
// listener if player is ready (including methods, like loadVideoById
player.addEventListener('onReady', function(event){
event.target.loadVideoById({
videoId: id,
startSeconds: start,
endSeconds: end
});
// pause player (my specific needs)
event.target.pauseVideo();
});
}
// if player is not defined, wait and try again
else {
setTimeout(loadVideo, 100, id, start, end);
}
}
// somewhere in the code
loadVideo('xxxxxxxx', 0, 3);
player.playVideo();
});
</script>
答案 3 :(得分:0)
其他答案无法澄清问题。
YouTube api确实令人困惑!这是因为YT.Player构造函数将dom引用返回到youtube播放器的iframe,而不是YT播放器对象。
为了获得对YT播放器的引用,我们需要监听onReady事件。
var ytPlayer;
var videoIframe = new YT.Player('player', {
videoId: 'xxxxxxx', // youtube video id
playerVars: {
'autoplay': 0,
'rel': 0,
'showinfo': 0
},
events: {
'onStateChange': onPlayerStateChange,
'onReady': function (ev) {
ytPlayer = ev.target;
}
}
});
答案 4 :(得分:0)
聚会只迟到了 6 年,我有解决方案。
问题是 YouTube API 不像 DOM shuffling Foundation 在打开模态时那样。
实现此目的的唯一方法是在打开模式后创建 YouTube 播放器:
function play_video(ytid) {
modal = new Foundation.Reveal($('#yt_modal'),{});
modal.open();
ytplayer = new YT.Player('ytplayer', {
videoId: ytid,
height: '390',
width: '640',
playerVars: {
'playsinline': 1
},
events: {
'onReady': whatever()
}
});
}
假设
<div id="ytplayer"></div>
在您的 Foundation 模态内。
哦,您每次都需要删除 iframe,否则 YouTube API 只会查找旧的 iframe(这不是它所期望的位置,因为模式已关闭且 DOM 已更改):
$(document).on('closed.zf.reveal', function(e) {
switch($(e.target).prop('id')) {
case 'yt_modal':
ytplayer.destroy();
break;
}
});
关于@Tosh 关于返回 iframe 引用的 API 的回答,就我可以通过将其与 onReady(ev.target) 返回的内容进行比较来确定,播放器不是真实的 - 它们看起来相同(所以不要不要像我一样走那条死胡同!)