Grease Monkey: Как я могу изменить порядок загрузки html-скриптов?

0

Я просматриваю этот сайт с ошибкой javascript на стороне клиента, вызванной загрузкой скриптов в неправильном порядке. Проблема в том, что у меня нет этого источника, но мне действительно нужно использовать сайт ASAP.

Есть ли способ сделать это с помощью greasemonkey? Проблема в том, что поскольку это загружается в элемент head, если я изменяю html, ошибка JS уже произошла. Но, если я обновляю изменения (по крайней мере, в хроме), мои локальные модификации исчезают.

В частности, элемент 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-скриптов?

Теги:
greasemonkey

1 ответ

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 являются единственными в элементе head. Представление countdown добавляет к надежности моего кода. Кроме того, countdown (вместе с script.async = false;) гарантирует как можно раньше загрузку трех сценариев в желаемом порядке.

  2. Я использую addEventListener потому что это рекомендуемая форма использования MDN.

Рекомендации:

qaru.site/questions/1754384/...

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

  • 0
    Можете ли вы объяснить, как это работает? Например, какой смысл в countdown ? Почему вы используете addEventListener вместо того, что я сделал?
  • 0
    @tieTYT Только что обновил код и добавил несколько заметок. Попробуйте это.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню