由于各种安全问题和范围界定问题,您无法从Greasemonkey脚本作用域运行ytplayer.getCurrentTime()
。
同样,click
事件处理程序必须在目标页面的作用域中运行以访问该函数。尝试这样做会产生undefined
和Error: Bad NPObject as private data!
的组合。
这意味着您必须为您的时间按钮“注入”click
处理程序。
但首先,这里有几个问题需要考虑:
- YouTube和谷歌大部分的网站,大量运用秒。为避免多次执行脚本时出现问题,请使用像
window.top === window.self
这样的检查来确保脚本仅在框架中运行或包含您所定位的页面。
- 尽量避免使用
innerHTML
和内联样式。这将使代码更容易维护,在许多情况下更快,并且不太可能引发意外的副作用。
把所有的一起,这里就是你的完整的脚本重构:
// ==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()
等,当点击那个按钮。这需要跨范围进行消息传递。 请参阅this answer或打开一个新的问题,当你到那个部分。
非常感谢您的回复和解释。 的确我会用'GM_setValue()'。 所以我必须开一个新的问题? 再一次,谢谢你:-) – Romaric
不客气。乐意效劳。 –