Grease Monkey:如何更改加载html脚本的顺序?

时间:2013-12-01 08:44:46

标签: javascript html greasemonkey

我正在查看此网站,该网站由于脚本以错误的顺序加载而导致客户端javascript错误。问题是我没有这个来源,但我确实需要尽快使用该网站。

有没有办法用greasemonkey做到这一点?问题是,由于这是在head元素中加载的,如果我修改了html,则JS错误已经发生。但是,如果我刷新更改(至少在chrome中),我的本地修改就会消失。

具体来说,html head元素包含:

<script 
    language="javascript" 
    src="/scripts/util.js" 
    type="text/javascript"></script>
<script 
    language="javascript" 
    src="/scripts/scriptaculous/prototype.js" 
    type="text/javascript"></script>
<script 
    language="javascript" 
    src="/scripts/scriptaculous/scriptaculous.js" 
    type="text/javascript"></script>

要解决这个问题,需要像这样:

<script 
    language="javascript" 
    src="/scripts/scriptaculous/prototype.js" 
    type="text/javascript"></script>
<script 
    language="javascript" 
    src="/scripts/scriptaculous/scriptaculous.js" 
    type="text/javascript"></script>
<script 
    language="javascript" 
    src="/scripts/util.js" 
    type="text/javascript"></script>

注意util.js如何移到底部。

我非常接近使用这个来源的油脂猴子脚本:

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

var loaded = false;

var loadScript = function(scriptName) {

    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = scriptName;
    head.appendChild(script);

};

window.onload = function() {
    loaded = true;
    loadScript('https://hostwithbug/scripts/scriptaculous/prototype.js');
    loadScript('https://hostwithbug/scripts/scriptaculous/scriptaculous.js');
    loadScript('https://hostwithbug/scripts/util.js');
};


document.onbeforescriptexecute = function() {   //control whether scripts get executed at all. FireFox feature
    return loaded;  
}

但我得到的错误是:

A call to document.write() from an asynchronously-loaded external script was ignored. @ https://hostwithbug/scripts/scriptaculous/scriptaculous.js:30

我不知道怎么解决这个问题。也许有一些方法让我用我选择的一个替换head标签?据我所知,它必须在head被渲染之前发生,以避免此错误。我还没有找到任何办法。

无论如何,我正在寻找标题中问题的解决方案:如何更改加载html脚本的顺序?

1 个答案:

答案 0 :(得分:1)

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

var countdown = 3;

var loadScript = function(scriptName) {

        var head = document.getElementsByTagName('head')[0];
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = scriptName;
        script.async = false;
        head.appendChild(script);

};

document.addEventListener('beforescriptexecute', function(e) {

        var src = e.target.src;
        if (src == '/scripts/util.js' || 
        src == '/scripts/scriptaculous/prototype.js' || 
        src == '/scripts/scriptaculous/scriptaculous.js') {
                e.preventDefault();
                e.stopPropagation();
                if(!--countdown) {
                        loadScript('https://hostwithbug/scripts/scriptaculous/prototype.js');
                        loadScript('https://hostwithbug/scripts/scriptaculous/scriptaculous.js');
                        loadScript('https://hostwithbug/scripts/util.js');
                }
        }

}, true);

注意:

  1. 我使用countdown来监控我们所关注的脚本的执行情况,因为我不确定您提到的三个script元素是否是{{1}中唯一的元素元素。介绍head增加了我的代码的健壮性。此外,countdown(以及countdown)确保我们尽可能早地按所需顺序加载三个脚本。

  2. 我使用的是script.async = false;,因为它是the recommended form of usage on MDN

  3. 参考文献:

    https://stackoverflow.com/a/3236373/735271

    https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#Attributes