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

How to call Greasemonkey#39;s GM_ functions from code that must run in the target page scope?(如何从必须在目标页面范围内运行的代码中调用 Greasemonkey 的 GM_ 函数?)
本文介绍了如何从必须在目标页面范围内运行的代码中调用 Greasemonkey 的 GM_ 函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里问了一个问题并得到了答案:如何调用Greasemonkey 的这个 YouTube 功能?

I asked a question and got an answer here: How to call this YouTube function from Greasemonkey?

该代码有效,并向页面添加了一个按钮,用于捕获视频时间.
但是,关键部分必须在目标页面范围内运行——Greasemonkey 的 GM_ 函数不可用.

That code works and adds a button to the page, which captures the video time.
But, the key part must run in the target-page scope -- where Greasemonkey's GM_ functions are not available.

我想用 GM_setValue() 来记录视频时间.如何从按钮的 click 处理程序中调用 GM_setValue()?

I want to use GM_setValue() to record the video time. How do I call GM_setValue() from my button's click handler?

这里是完整脚本的相关部分(右键保存):

... ...

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

... ...


谢谢你:-)

推荐答案

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

To use Greasemonkey's GM_ functions from code that must run in the page scope (Such as your timeBtn click handler), do the following:

  1. 让页面范围代码使用 postMessage 以字符串格式发送数据.
  2. 让 Greasemonkey 脚本监听相应的消息,并使用消息数据调用所需的 GM_ 函数.
  3. 使用 JSON 安全地将数据打包成字符串.
  1. Have the page-scope code use postMessage to send the data in string format.
  2. Have the Greasemonkey script listen for the appropriate messages and call the desired GM_ function(s) with the message data.
  3. Use JSON to safely package data in strings.

在你的代码中加入window.postMessage()window.addEventListener("message"...,就变成了:

Adding window.postMessage () and window.addEventListener ("message"... to your code, it becomes:

... ...

//-- 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 并搜索 videoMarkedTime 来查看存储的值.


You can see the stored value by opening about:config and searching for videoMarkedTime.

这篇关于如何从必须在目标页面范围内运行的代码中调用 Greasemonkey 的 GM_ 函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Update another component when Formik form changes(当Formik表单更改时更新另一个组件)
Formik validation isSubmitting / isValidating not getting set to true(Formik验证正在提交/isValiating未设置为True)
React Validation Max Range Using Formik(使用Formik的Reaction验证最大范围)
Validation using Yup to check string or number length(使用YUP检查字符串或数字长度的验证)
Updating initialValues prop on Formik Form does not update input value(更新Formik表单上的初始值属性不会更新输入值)
password validation with yup and formik(使用YUP和Formick进行密码验证)