admin管理员组文章数量:1287583
I'm having an issue with the following code, but I'm not sure where the problem is.
On my master page, in javascript, I have an array defined to hold a list of YouTubePlayer
objects that I create. I also load the YouTube API here.
I also have (sometime several) YouTube user control(s) that contains the YouTube div in a bootstrap modal. It also contains a JavaScript for pushing a new YouTubePlayer
object to the array in the master page js. Lastly, on the user control, I define methods for auto-starting and stopping the video on the 'shown' and 'hide' events of the bootstrap modal.
Finally, to (hopefully) solve the race condition between the document being loaded and the YouTube API being loaded, I set two bool variables (one for document, one for API), and check both for true before calling an initVideos function which iterates through the array of YouTubePlayer
objects and initializes them, setting the YT.Player
object in the window. Part of the issue, I think, is that I can't statically set window.player1
etc., because I never know how many YouTube user controls will be loaded.
The problem is whenever the bootstrap modal events fire, the YT.Player
object I retrieve from the window doesn't contain the methods for playVideo()
and pauseVideo()
.
On my master page:
$(document).ready(function () {
window.docReady = true;
if (window.apiReady)
initVideos();
});
function onYouTubeIframeAPIReady() {
window.apiReady = true;
if (window.docReady)
initVideos();
initVideos();
}
function initVideos() {
if (typeof ytPlayerList === 'undefined')
return;
for (var i = 0; i < ytPlayerList.length; i++) {
var player = ytPlayerList[i];
var pl = new YT.Player(player.DivId, {
playerVars: {
'autoplay': '0',
'controls': '1',
'autohide': '2',
'modestbranding': '1',
'playsinline': '1',
'rel': '0',
'wmode': 'opaque'
},
videoId: player.VideoId,
events: {
'onStateChange': player.StateChangeHandler
}
});
window[player.Id] = pl;
}
}
And on the user control:
window.ytPlayerList.push({
Id: "<%=ClientID%>player",
DivId: "<%=ClientID%>player",
VideoId: "<%=VideoId%>",
StateChangeHandler: hide<%=ClientID%>Player
});
function hide<%=ClientID %>Player(state) {
if (state.data == '0') {
hide<%=ClientID %>Video();
}
}
function show<%=ClientID %>Video() {
$('#<%=ClientID %>video-modal').modal('show');
}
function hide<%=ClientID %>Video() {
$('#<%=ClientID %>video-modal').modal('hide');
}
$(document).ready(function() {
$("#<%=ClientID%>Video").click(function() {
show<%=ClientID%>Video();
});
$("#<%=ClientID %>video-modal").on('shown', function () {
window["<%=ClientID%>player"].playVideo();
});
$("#<%=ClientID %>video-modal").on('hide', function () {
window["<%=ClientID%>player"].pauseVideo();
});
});
This may be a lack of js expertise, but I'm absolutely stuck. Any help would be greatly appreciated. Also, for reference, the exception I get is
Uncaught TypeError: window.ctl100_phContent_ctl100player.playVideo is not a function
I'm having an issue with the following code, but I'm not sure where the problem is.
On my master page, in javascript, I have an array defined to hold a list of YouTubePlayer
objects that I create. I also load the YouTube API here.
I also have (sometime several) YouTube user control(s) that contains the YouTube div in a bootstrap modal. It also contains a JavaScript for pushing a new YouTubePlayer
object to the array in the master page js. Lastly, on the user control, I define methods for auto-starting and stopping the video on the 'shown' and 'hide' events of the bootstrap modal.
Finally, to (hopefully) solve the race condition between the document being loaded and the YouTube API being loaded, I set two bool variables (one for document, one for API), and check both for true before calling an initVideos function which iterates through the array of YouTubePlayer
objects and initializes them, setting the YT.Player
object in the window. Part of the issue, I think, is that I can't statically set window.player1
etc., because I never know how many YouTube user controls will be loaded.
The problem is whenever the bootstrap modal events fire, the YT.Player
object I retrieve from the window doesn't contain the methods for playVideo()
and pauseVideo()
.
On my master page:
$(document).ready(function () {
window.docReady = true;
if (window.apiReady)
initVideos();
});
function onYouTubeIframeAPIReady() {
window.apiReady = true;
if (window.docReady)
initVideos();
initVideos();
}
function initVideos() {
if (typeof ytPlayerList === 'undefined')
return;
for (var i = 0; i < ytPlayerList.length; i++) {
var player = ytPlayerList[i];
var pl = new YT.Player(player.DivId, {
playerVars: {
'autoplay': '0',
'controls': '1',
'autohide': '2',
'modestbranding': '1',
'playsinline': '1',
'rel': '0',
'wmode': 'opaque'
},
videoId: player.VideoId,
events: {
'onStateChange': player.StateChangeHandler
}
});
window[player.Id] = pl;
}
}
And on the user control:
window.ytPlayerList.push({
Id: "<%=ClientID%>player",
DivId: "<%=ClientID%>player",
VideoId: "<%=VideoId%>",
StateChangeHandler: hide<%=ClientID%>Player
});
function hide<%=ClientID %>Player(state) {
if (state.data == '0') {
hide<%=ClientID %>Video();
}
}
function show<%=ClientID %>Video() {
$('#<%=ClientID %>video-modal').modal('show');
}
function hide<%=ClientID %>Video() {
$('#<%=ClientID %>video-modal').modal('hide');
}
$(document).ready(function() {
$("#<%=ClientID%>Video").click(function() {
show<%=ClientID%>Video();
});
$("#<%=ClientID %>video-modal").on('shown', function () {
window["<%=ClientID%>player"].playVideo();
});
$("#<%=ClientID %>video-modal").on('hide', function () {
window["<%=ClientID%>player"].pauseVideo();
});
});
This may be a lack of js expertise, but I'm absolutely stuck. Any help would be greatly appreciated. Also, for reference, the exception I get is
Uncaught TypeError: window.ctl100_phContent_ctl100player.playVideo is not a function
Share
Improve this question
edited Apr 28, 2015 at 12:10
Praxis Ashelin
5,2272 gold badges21 silver badges46 bronze badges
asked Apr 17, 2015 at 21:05
JackJack
9502 gold badges17 silver badges36 bronze badges
3
-
Is it intentional that you are firing
initVideos()
twice inonYouTubeIframeAPIReady()
function? – Praxis Ashelin Commented Apr 28, 2015 at 12:14 - possible duplicate of .playVideo() - not a function? or playVideo doesn't work – Praxis Ashelin Commented Apr 28, 2015 at 12:28
- Could you paste some of the generated HTML please ? That'll make it more easy for me to reproduce the issue. – Jochen van Wylick Commented Apr 29, 2015 at 16:24
1 Answer
Reset to default 9 +25So the problem is that the video only gets that playVideo()
method when the YouTube API has finished loading the video element. This video element is loaded async, so the code execution will continue with the $(document).ready(function() {
jQuery code where it will try to attach the playVideo()
functions which at that point in time - do not yet exist.
I've reproduced this error in that HTML/JS page:
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-patible" content="ie=edge">
<title></title>
</head>
<body>
<div id="ctl100_phContent_ctl100player" style="border:1px solid red;"></div>
<div id="ctl100_phContent_ctl101player" style="border:1px solid red;"></div>
<div id="ctl100_phContent_ctl102player" style="border:1px solid red;"></div>
<script src="https://www.youtube./iframe_api"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.6.2.min.js"><\/script>')</script>
<script>
window.ytPlayerList = [];
window.players = [];
window.ytPlayerList.push({ Id: 'ctl100_phContent_ctl100player', DivId: 'ctl100_phContent_ctl100player', VideoId: 'IaHxPi9dM7o', StateChangeHandler: 'hide_player_1' });
window.ytPlayerList.push({ Id: 'ctl100_phContent_ctl101player', DivId: 'ctl100_phContent_ctl101player', VideoId: 'IaHxPi9dM7o', StateChangeHandler: 'hide_player_2' });
window.ytPlayerList.push({ Id: 'ctl100_phContent_ctl102player', DivId: 'ctl100_phContent_ctl102player', VideoId: 'IaHxPi9dM7o', StateChangeHandler: 'hide_player_3' });
function onYouTubeIframeAPIReady() {
initVideos();
}
function initVideos() {
for (var i = 0; i < ytPlayerList.length; i++) {
var player = ytPlayerList[i];
var pl = new YT.Player(player.DivId, {
height: '390',
width: '640',
videoId: player.VideoId,
});
window[player.Id] = pl;
}
}
window.ctl100_phContent_ctl100player.playVideo();
</script>
</body>
</html>
This gives me the same error you describe. So in order to test my theory ( and make sure there were no other script errors ) I did this:
setTimeout(function() {
window.ctl100_phContent_ctl100player.playVideo()
}, 1000);
That did work. So indeed this seems to the problem. However - we don't know for sure that 1000ms is enough to guarantee that the player is initialized. So what you could do - if you want to not refactor too much - is start listening for the onready
events of the player:
function initVideos() {
for (var i = 0; i < ytPlayerList.length; i++) {
var player = ytPlayerList[i];
var pl = new YT.Player(player.DivId, {
height: '390',
width: '640',
videoId: player.VideoId,
events: {
'onReady': window[player.Id + '_ready']
}
});
window[player.Id] = pl;
}
}
Which assumes you used codegeneration to create functions like:
function ctl100_phContent_ctl100player_ready() {
// Hook up the hide() / onShow() and other behaviors here
// ... to prove that playVideo() is a function here, I'm calling it
window.ctl100_phContent_ctl100player.playVideo();
}
function ctl100_phContent_ctl101player_ready() {
window.ctl100_phContent_ctl101player.playVideo();
}
function ctl100_phContent_ctl102player_ready() {
window.ctl100_phContent_ctl102player.playVideo();
}
So this is not a copy-paste solution for you problem but should give you insight into why the code is not working. There are probably more elegant ways to achieve what you're trying to do, but let's just keep the fix simple for now.
Let me know if it worked or if you have any other questions.
本文标签: javascriptLoading Multiple YouTube Videos iFrame APIStack Overflow
版权声明:本文标题:javascript - Loading Multiple YouTube Videos iFrame API - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741314300a2371828.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论