0

我使用的一个网站是用一些非常好的 JavaScript 编写的。几乎没有任何全局变量,到处都是闭包,它使用严格模式。这使得将我自己的功能注入网站变得非常困难。

网站客户端对象在jQuery.ready()调用中初始化:

$(window).ready(function () {
    var a, b, c, d;

    // Setup global data [...]
    // Setup configuration [...]

    a = GlobalFoo.ConstructorA();
    b = GlobalFoo.ConstructorB(a);
    // Really wish I could put stuff here
    c = GlobalFoo.ConstructorC(a, b);
    d = GlobalFoo.ConstructorD(b, c);
    // etc.
});

例如,如何b.someMethod()在调用其他构造函数之前用我自己的代码替换?

我可以阻止准备好的事件发生或用我自己的代码替换它吗?由于它很小,我可以在我的代码中复制一个修改后的版本。

4

1 回答 1

2

经过一番搜索后,我发现了 dindog 的这个精彩页面。GreaseSpot wiki 上也有此页面@run-at描述.

@run-at允许您的用户脚本在所有其他代码之前运行。该beforescriptexecute事件允许您在执行之前检查每个脚本。然后,您可以跳过或修改它。

我的最终解决方案是:

// ==UserScript==
// @name        ...
// @description ...
// @namespace   ...
// @include     ...
// @version     1
// @run-at      document-start
// @grant       none
// ==/UserScript==

(function (w) {
    // Remove the current jQuery ready code
    function pre_script_execute_handler (e) {
        var target = e.target;
        if (target.innerHTML.indexOf("$(window).ready(") != -1) {
            console.log('Removed ready');
            e.preventDefault();
            e.stopPropagation();
            addReady();
        }
    }
    w.addEventListener('beforescriptexecute', pre_script_execute_handler);

    // Add new jQuery ready code
    function addReady () {
        console.log('Adding new ready');
        w.$(window).ready(function () {
            console.log('Our ready called');
        });
    }


}) (unsafeWindow);
于 2013-09-29T00:24:35.907 回答