如何从Greasemonkey调用此YouTube功能? [英] How to call this YouTube function from Greasemonkey?
问题描述
我正在尝试使用Greasemonkey显示带有观看视频时间的提醒。
I'm trying to display an alert with the time watched of the video with Greasemonkey.
我的脚本:
// ==UserScript==
// @name Time YouTube
// @description Does not work ! Help !
// @namespace time_youtube
// @include *youtube.com/watch*
// @grant GM_setValue
// @icon http://aux3.iconpedia.net/uploads/520882026785186105.png
// @version 1.3
// ==/UserScript==
ytplayer = document.getElementById ("movie_player");
var time = document.createElement ('a');
time.innerHTML = '<a style="position: fixed; top: 200px; left: 3px; color:black;">Time</a>';
//time.addEventListener ('click', function(){GM_setValue('url_time',(document.location.href) + '&t=' + (ytplayer.getCurrentTime()));}, false);
time.addEventListener ('click',
function () {
alert (ytplayer.getCurrentTime() );
},
false
);
document.body.appendChild (time);
但这不起作用。
But this does not work.
你能帮帮我吗?谢谢!
推荐答案
由于各种安全和范围问题,您无法运行 ytplayer.getCurrentTime()来自Greasemonkey脚本范围的
。
Due to various security and scoping issues, you cannot run ytplayer.getCurrentTime()
from the Greasemonkey script scope.
同样,单击
事件处理程序必须在目标页面的范围内运行才能访问该函数。尝试不这样做会产生 undefined
和组合错误:坏NPObject作为私人数据!
。
Likewise, the click
event handler must run in the target page's scope to access that function. Attempts to do otherwise will yield combinations of undefined
and Error: Bad NPObject as private data!
.
这意味着你必须为你的时间按钮注入点击
处理程序。
但首先,这里是还有一些需要考虑的问题:
This means that you must "Inject" the click
handler for your time button.
But first, here's a few more issues to consider:
- Youtube和大多数Google网站大量使用
< iframe>
秒。为避免多次执行脚本时出现问题,请使用window.top === window.self
等检查,以确保脚本仅在框架中运行或包含您要定位的页面。 - 尽量避免使用
innerHTML
和内联样式。这将使代码更容易维护,在许多情况下更快,并且不太可能触发意外的副作用。
- Youtube, and most Google sites, make extensive use of
<iframe>
s. To avoid problems with multiple executions of your script, use checks likewindow.top === window.self
to ensure that the script only runs in the frame(s) or containing page that you are targeting. - Avoid using
innerHTML
and inline styles as much as possible. This will make the code easier to maintain, faster in many instances, and less likely to trigger unexpected side effects.
将所有这些放在一起,这是您的完整脚本重构:
Putting that all together, here is your complete script refactored:
// ==UserScript==
// @name Time YouTube
// @description Does not work ! Help !
// @namespace time_youtube
// @include *youtube.com/watch*
// @icon http://aux3.iconpedia.net/uploads/520882026785186105.png
// @grant GM_setValue
// @grant GM_addStyle
// @version 1.3
// ==/UserScript==
//-- Only run in the top page, not the various iframes.
if (window.top === window.self) {
var timeBtn = document.createElement ('a');
timeBtn.id = "gmTimeBtn";
timeBtn.textContent = "Time";
//-- Button is styled using CSS, in GM_addStyle, below.
document.body.appendChild (timeBtn);
addJS_Node (null, null, activateTimeButton);
}
function activateTimeButton () {
var timeBtn = document.getElementById ("gmTimeBtn");
if (timeBtn) {
timeBtn.addEventListener ('click',
function () {
var ytplayer = document.getElementById ("movie_player");
//-- IMPORTANT: GM_functions will not work here.
console.log ("getCurrentTime(): ", ytplayer.getCurrentTime() );
//alert (ytplayer.getCurrentTime() );
},
false
);
}
else {
alert ("Time button not found!");
}
}
//-- Style and position our button the CSS way.
GM_addStyle ( " \
#gmTimeBtn { \
position: fixed; \
top: 200px; \
left: 3px; \
color: black; \
margin: 0; \
padding: 0; \
} \
" );
//-- This is a standard-ish utility function...
function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
var D = document;
var scriptNode = D.createElement ('script');
if (runOnLoad) {
scriptNode.addEventListener ("load", runOnLoad, false);
}
scriptNode.type = "text/javascript";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()';
var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
targ.appendChild (scriptNode);
}
最后,从您的脚本,看起来你希望最终在点击该按钮时使用 GM_setValue()
等。这需要跨范围进行消息传递。 请参阅此答案 ,或在您到达该部分时打开一个新问题。
Finally, from your script, it looks like you hope to eventually use GM_setValue()
, etc., when clicking that button. That requires messaging across scopes. See this answer or open a new question when you get to that part.
这篇关于如何从Greasemonkey调用此YouTube功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!