如何使用用户脚本覆盖函数?

时间:2014-01-22 00:38:26

标签: javascript userscripts

我想更改部分网页显示,是否可以用usercript覆盖某个功能?

以下是我想覆盖的功能(也是found Here):

function StartDrawing() {
    if ((typeof (systemsJSON) != "undefined") && (systemsJSON != null)) {
        var stellarSystemsLength = systemsJSON.length;
        $('#mapDiv').empty();
        if (stellarSystemsLength > 0) {
            InitializeRaphael();

            var i = 0;
            for (i = 0; i < stellarSystemsLength; i++){
                var stellarSystem = systemsJSON[i];
                DrawSystem(stellarSystem)
            }
        }
    }
}

这将允许我运行自己的绘图算法。

如何使用chrome(或Firefox)中的用户脚本执行此操作?

2 个答案:

答案 0 :(得分:5)

请参阅"Accessing Variables (and Functions) from Greasemonkey to Page & vice versa

用户脚本与目标页面分开,因此您无法在不了解上下文的情况下覆盖函数或变量...

IF 该函数是全局的(看起来可能就是这种情况),您可以inject新的函数定义:

function StartDrawing () {
    // WHATEVER YOU WANT FOR THE NEW CODE GOES HERE.
}

addJS_Node (StartDrawing);

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);
}


这适用于几乎所有支持用户脚本的浏览器。

在某些情况下,您可能需要通过触发窗口load事件和/或检查该功能是否已存在来延迟加载。

根据您的浏览器的不同,您可能还有其他选项(请参阅上面的链接Q&amp; A):

  • Firefox + Greasemonkey 中,您可以使用@grant none模式或unsafeWindow
  • Chrome + Tampermonkey 中,您通常可以使用unsafeWindow@grant none模式也可能有效,但我自己没有测试过。




如果函数不是全局函数:

然后在 Firefox 中,您必须覆盖JS源代码。请参阅"Stop execution of javascript function (client side) or tweak it"

在Chrome中,你大部分都不走运(最近几个月前已经过验证)。

答案 1 :(得分:2)

javascript允许重新定义函数,如果函数存在。如果重新定义,该功能将被覆盖而没有任何警告。

如果你想要旧的功能工作,你可以采取以下方式。

var _oldStartDrawing =StartDrawing;
function StartDrawing() {
     _oldStartDrawing();//if you need previous function
     //extend code here;
}