用 JavaScript 或 jQuery 监听 Youtube 事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7988476/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Listening for Youtube Event in JavaScript or jQuery
提问by Dave Kiss
I have a slider which includes 4 youtube videos that are embedded via the iframe embed code
我有一个滑块,其中包含 4 个通过 iframe 嵌入代码嵌入的 youtube 视频
http://www.youtube.com/embed/'.$i.'?enablejsapi=1
http://www.youtube.com/embed/'.$i.'?enablejsapi=1
I'm trying to make the onStateChange
event of any of the four videos call a function I have called stopCycle()
which will stop the slider when the video begins to play. The iframes do not have an id. I'm not sure about how to capture this event properly and could use any advice as to what i'm doing wrong.
我试图让onStateChange
四个视频中的任何一个的事件调用我调用的函数,该函数stopCycle()
将在视频开始播放时停止滑块。iframe 没有 ID。我不确定如何正确捕获此事件,并且可以使用任何关于我做错了什么的建议。
<script charset="utf-8" type="text/javascript" src="http://www.youtube.com/player_api"></script>
var playerObj = document.getElementById("tab2"); // the container for 1 of the 4 iframes
playerObj.addEventListener("onStateChange", "stopCycle");
function stopCycle(event) {
alert('Stopped!');
}
回答by Rob W
The YouTube Frame APIdoessupport existing frames. To improve the usage, I have created some helper functions. Have a look at the code + comments below and the demo: http://jsfiddle.net/YzvXa/197
在YouTube的框架API不支持现有的框架。为了改进使用,我创建了一些辅助函数。看看下面的代码+评论和演示:http: //jsfiddle.net/YzvXa/197
To bind functions to existent frames, you have topass an ID reference to the frame. In your case, the frame is contained within a container with id="tab2"
. I have defined a custom function for an easier implementation:
要将函数绑定到现有框架,您必须将 ID 引用传递给框架。在您的情况下,框架包含在带有id="tab2"
. 我定义了一个自定义函数,以便于实现:
function getFrameID(id){
var elem = document.getElementById(id);
if (elem) {
if(/^iframe$/i.test(elem.tagName)) return id; //Frame, OK
// else: Look for frame
var elems = elem.getElementsByTagName("iframe");
if (!elems.length) return null; //No iframe found, FAILURE
for (var i=0; i<elems.length; i++) {
if (/^https?:\/\/(?:www\.)?youtube(?:-nocookie)?\.com(\/|$)/i.test(elems[i].src)) break;
}
elem = elems[i]; //The only, or the best iFrame
if (elem.id) return elem.id; //Existing ID, return it
// else: Create a new ID
do { //Keep postfixing `-frame` until the ID is unique
id += "-frame";
} while (document.getElementById(id));
elem.id = id;
return id;
}
// If no element, return null.
return null;
}
// Define YT_ready function.
var YT_ready = (function() {
var onReady_funcs = [], api_isReady = false;
/* @param func function Function to execute on ready
* @param func Boolean If true, all qeued functions are executed
* @param b_before Boolean If true, the func will added to the first
position in the queue*/
return function(func, b_before) {
if (func === true) {
api_isReady = true;
while (onReady_funcs.length) {
// Removes the first func from the array, and execute func
onReady_funcs.shift()();
}
} else if (typeof func == "function") {
if (api_isReady) func();
else onReady_funcs[b_before?"unshift":"push"](func);
}
}
})();
// This function will be called when the API is fully loaded
function onYouTubePlayerAPIReady() {YT_ready(true)}
// Load YouTube Frame API
(function() { // Closure, to not leak to the scope
var s = document.createElement("script");
s.src = (location.protocol == 'https:' ? 'https' : 'http') + "://www.youtube.com/player_api";
var before = document.getElementsByTagName("script")[0];
before.parentNode.insertBefore(s, before);
})();
//
Previously, core functions were defined. Look ahead for the implementation:
//
以前,定义了核心功能。展望实施:
var player; //Define a player object, to enable later function calls, without
// having to create a new class instance again.
// Add function to execute when the API is ready
YT_ready(function(){
var frameID = getFrameID("tabs2");
if (frameID) { //If the frame exists
player = new YT.Player(frameID, {
events: {
"onStateChange": stopCycle
}
});
}
});
// Example: function stopCycle, bound to onStateChange
function stopCycle(event) {
alert("onStateChange has fired!\nNew state:" + event.data);
}
If you want to invoke additional functions at a later point, e.g. mute a video, use:
如果您想稍后调用其他功能,例如将视频静音,请使用:
player.mute();
- If you only have to call simple single-directionfunctions, it's not necessary to use this code. Instead, use the function
callPlayer
as defined at this answer. - If you want to implement this feature for multiple frames, simultaneously, have a look at this answer. Also includes a detailed explanation of
getFrameID
andYT_ready
.
回答by topek
You can use the tubeplayerplugin, it comes with lots of events to listen for.
您可以使用tubeplayer插件,它带有许多要侦听的事件。
回答by ceasar
Since yesterday this isn't working any more. The onStateChange isn't fired. Jeffrey posted an quick fix but I am not able to update the above answer
从昨天开始,这不再起作用了。onStateChange 不会被触发。杰弗里发布了一个快速修复,但我无法更新上述答案
More info about this issue https://code.google.com/p/gdata-issues/issues/detail?id=4706
有关此问题的更多信息https://code.google.com/p/gdata-issues/issues/detail?id=4706
Got it working :-) with the fix
得到它的工作:-) 与修复
Add the following function
添加以下功能
function onReady() {
player.addEventListener('onStateChange', function(e) {
console.log('State is:', e.data);
});
}
and before "onStateChange": stopCycle add "onReady": onReady,
在 "onStateChange": stopCycle 之前添加 "onReady": onReady,
回答by ingridsede
I have this feature on my chat that enables users to post vids from youtube. The url of the vid is attached as source of existing iframe with id.
我的聊天中有这个功能,让用户可以从 youtube 上发布视频。vid 的 url 作为带有 id 的现有 iframe 的来源附加。
What i notice is that -although ?enablejsapi=1 is added - that the script only works far existing iframes on pageload.
我注意到的是 - 尽管添加了 ?enablejsapi=1 - 该脚本仅适用于页面加载中现有的 iframe。
How would one go about when wanting this script to bind after a new source is set for the iframe?
在为 iframe 设置新源后希望绑定此脚本时,将如何进行?