如何从必须在目标页面范围内运行的代码调用Greasemonkey的GM_函数?

我问了一个问题,并在这里得到了答案: 如何从Greasemonkey调用这个YouTubefunction?

该代码的作品,并在页面上添加一个button,捕捉video时间。
但是,关键部分必须运行在目标页面范围内 – Greasemonkey的GM_函数不可用。

我想用GM_setValue()来loggingvideo时间。 如何从我的button的click处理程序中调用GM_setValue()

以下是完整脚本的相关部分(右键单击以保存) :

 ... ... //-- 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!"); } } ... ... 

谢谢 :-)

要使用必须在页面范围内运行的代码(如timeBtn点击处理程序)使用Greasemonkey的GM_函数,请执行以下操作:

  1. 让页面范围代码使用postMessage以string格式发送数据。
  2. 让Greasemonkey脚本监听相应的消息,并用消息数据调用所需的GM_函数。
  3. 使用JSON安全地将数据打包到string中。

添加window.postMessage ()window.addEventListener ("message"...到你的代码,它变成:

 ... ... //-- 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); window.addEventListener ("message", receiveTimeMessage, false); } function activateTimeButton () { var timeBtn = document.getElementById ("gmTimeBtn"); if (timeBtn) { timeBtn.addEventListener ('click', function () { var ytplayer = document.getElementById ("movie_player"); /*-- GM_functions will not work here, so send the data back to the GM script scope. */ //-- Tag the message, we may not be the only ones sending. var messageTxt = JSON.stringify ( {currentVidTime: ytplayer.getCurrentTime ()} ); window.postMessage (messageTxt, "*"); }, false ); } else { alert ("Time button not found!"); } } function receiveTimeMessage (event) { var messageJSON; try { messageJSON = JSON.parse (event.data); } catch (zError) { // Do nothing } if ( ! messageJSON || ! messageJSON.currentVidTime) return; //-- Message is not for us. /*--- We have a time value, set it with GM_setValue () But, WARNING: First make sure that the stored value is a safe string. GM_setValue() crashes on just about anything else. */ var safeValue = JSON.stringify (messageJSON.currentVidTime); GM_setValue ("videoMarkedTime", safeValue); console.log ("Video time recorded with GM_setValue ()."); } ... ... 

您可以通过打开about:config并searchvideoMarkedTime来查看存储的值。