【问题标题】:How to overwrite a function using a userscript?如何使用用户脚本覆盖函数?
【发布时间】:2014-01-22 00:38:25
【问题描述】:

我想更改部分网页显示,是否可以用用户脚本覆盖功能?

下面是我想要覆盖的函数(也是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)
            }
        }
    }
}

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

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

【问题讨论】:

    标签: javascript userscripts


    【解决方案1】:

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

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

    如果函数是全局的(看起来可能是这种情况),你可以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 事件和/或检查函数是否已存在。

    根据您的浏览器,您可能有其他选项(请参阅上面链接的问答):

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




    如果函数不是全局的:

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

    在 Chrome 中,您大多不走运(最近一次验证是 6 个月前)。

    【讨论】:

      【解决方案2】:

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

      如果你想让旧功能也能正常工作,你可以按照以下方式进行。

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

      【讨论】:

      • 您的错字会导致重大问题。
      • @epascarello 你说得对,我总是忘记那个机制。
      • 这看起来很简单,不像公认的答案。有什么注意事项吗?
      • @M.Volf 如果原页面脚本中使用的函数稍后按事件调用,则原页面脚本 write 调用新的覆盖脚本。理论上,如果通过事件调用函数,可能会影响其他用户脚本。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-31
      • 2020-04-10
      • 2013-06-15
      • 2010-10-25
      • 1970-01-01
      相关资源
      最近更新 更多