在我的Greasemonkey脚本中,我想覆盖网页中仍然存在的功能。

所以我正在使用以下JavaScript代码:

var oldDoWork = DoWork;

unsafeWindow.DoWork = function()
{
    // Do some new work
    ...

    oldDoWork(); // Call the old function
}

有用。

但是该方法存在两个问题:

  1. Greasemonkey说, unsafeWindow功能是一个安全问题。
  2. 在这个新函数中,我们不能使用GM_getValueGM_setValue 使用计时器的解决方法会导致异步作业的其他一些问题。

我如何在不使用unsafeWindow情况下管理上述代码?

===============>>#1 票数:1 已采纳

为了避免出现unsafeWindow,可以使用:

location.assign("javascript:YOUR_CODE_GOES_HERE");

但这也不会让您使用GM_ *函数。

而“不在GM范围内”使用GM_ *的唯一方法是使用计时器。

因此,基本上,您的问题的答案是:您以正确的方式,只是对此无能为力。

如果您的函数未返回任何内容,那么我建议您使用location.assign

===============>>#2 票数:0

如果要避免使用unsafeWindow ,请向页面中注入与页面的JS交互的代码。 参见下面的addJS_Node()

要从此类事件中触发GM_函数,您应该能够通过以下方式进行交互:

  • 编写节点并收听DOMSubtreeModified (在W3C规范中已弃用)。 但是, FF / GM中的错误暂时阻止了这种情况

  • 发送自定义事件。 再次, GM / FF错误和功能暂时阻止了该操作
    请注意,例如, click事件可以在用户实际单击时调用使用GM_函数的代码。 但是,以编程方式生成相同的click事件,并且失败并显示"Greasemonkey access violation: unsafeWindow cannot call..."错误。

因此,目前,解决方法仍然是使用计时器, 如果需要,可以避免使用unsafeWindow

//--- Put everything that goes into the main page, inside myJS().
function myJS () {

    window.oldDoWork = DoWork;

    window.DoWork = function() {
        // Do some new work

        callGM_setValue ("From target page", "some value");

        window.oldDoWork(); // Call the old function
    }

    function callGM_setValue (varName, varValue) {

        //--- Generate and dispatch a synthetic event.
        var zEvent  = document.createEvent ("CustomEvent");
        zEvent.initCustomEvent (
            "messageToGM_setvalue", true, false,
            {Name: varName, Value: varValue}
        );

        document.body.dispatchEvent (zEvent);
    }
}

document.body.addEventListener (
    "messageToGM_setvalue", fireGM_setValue, false
);

function fireGM_setValue (zEvent) {

    /*--- setTimeout remains one of the few things that can cleanse
        the calling tree of it's "unsafe" origins.
    */
    setTimeout (function() {
        GM_setValue (zEvent.detail.Name, zEvent.detail.Value);
    }, 0);
}

addJS_Node (null, null, myJS);

function addJS_Node (text, s_URL, funcToRun) {
    var D           = document;
    var scriptNode  = D.createElement ('script');
    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);
}

  ask by WolveFred translate from so

未解决问题?本站智能推荐: