由於各種安全問題和範圍界定問題,您無法從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
不客氣。樂意效勞。 –