Подтвердить что ты не робот

Как запустить greasemonkey script до отображения содержимого страницы?

Я пишу плагин для Firefox и использую greasemonkey script для этого (я скомпилирую пользователя script с помощью этого инструмента http://arantius.com/misc/greasemonkey/script-compiler).

Проблема заключается в том, что script запускается после полной загрузки страницы. Это означает, что пользователь увидит просматриваемую страницу в ее первоначальной форме, а затем script применит сделанные мной изменения. Мой вопрос: есть ли способ запустить пользователя script до того, как содержимое страницы будет отображаться пользователю, так что пользователь будет только окончательной версией веб-сайта?

4b9b3361

Ответ 1

EDIT: этот пост был создан до реализации ключа @run-at в Greasemonkey - как отмечено Blaise, из Greasemonkey 0.9.8 вы можете теперь выполнить script, как только страница начнет загружаться.

@run-at document-start описывается в wiki следующим образом:

Старт новый, начиная с версии 0.9.8. script будет запускаться до документ начинает загрузку, поэтому перед запуском любого скрипта или загрузки изображений.

Обратите внимание, что это означает, что выполнение script выполняется (потенциально) до создания DOM и может привести к некорректному/необычному поведению. Вам понадобится (немного) больше, чем просто однострочное вхождение.

В Greaseemonkey Wiki есть еще несколько деталей: http://wiki.greasespot.net/Metadata_Block#.40run-at

Боковое примечание. Информация, которую я должен передать, специально связана с Greasemonkey в браузере. Я не уверен, что @run-at document-start хорошо работает с компилятором script - я предлагаю жить опасно.. Протестируйте его и узнайте!;]



В настоящее время невозможно запустить пользователя script до загрузки страницы.

Чтобы остановить мерцание, используя текущие версии Greasemonkey, вы можете попробовать добавить пользовательский стиль в свой профиль Firefox (который затем отменяется с помощью script), как описано в Greasemonkey wiki, но это также потребует от каждого из ваших пользователей сделать то же самое, чтобы извлечь выгоду из этого.

Это то, что было давно желательным, и просмотрев issue # 1103 на сайте Greasemonkey Github, кажется, что был создан рабочий прототип (но нет времени для его добавления в выпускную версию afaik).

Ответ 2

Используя @run-at document-start, как было предложено в ответе @kwah, мой script, выполненный до того, как содержимое, которое я хотел обработать, было в теле документа. В качестве обхода я установил интервал, выполняющий мой script 5 раз/сек до document.readyState == "complete" (или до 20 секунд).

Это хорошо сработало для моего случая:

// ==UserScript==
// ...
// @run-at      document-start
// ==/UserScript==

var greasemonkeyInterval = setInterval(greasemonkey, 200);
var greasemonkeyStart = (new Date()).getTime();

function greasemonkey() {

    // ...

    // waiting for readyState (or timeout)
    if (
        (new Date()).getTime() - greasemonkeyStart > 20000
        || document.readyState == "complete"
    ) {
        clearInterval(greasemonkeyInterval);
    }

};

Если вы более уверены в том, что контент будет там в документе, я думаю, что что-то вроде этого было бы более предпочтительным:

function greasemonkey() {

    if (
        document.readyState != "interactive"
        && document.readyState != "complete"
    ) {
        return;
    }

    // ...

    clearInterval(greasemonkeyInterval);

}

Ответ 3

В дополнение к предыдущим ответам я нашел решение, которое работает безупречно, как и предыдущие версии Firefox и GreaseMonkey. Прежде всего, запуск должен быть установлен в самый ранний момент, поэтому начало документа:

// @run-at      document-start

Поскольку DOM, вероятно, еще не загружен, дождитесь, когда документ получит готовое состояние интерактивного интерфейса:

document.onreadystatechange = function () {
    if (document.readyState === "interactive") {
       // Do something
    }
}

В то время как Greasemonkey реализует более или менее то же самое с концом документа, я заметил, что вышеприведенная техника работает быстрее. Используя это, я разрешил все проблемы, которые у меня были в Firefox, с мигающими/прыгающими экранами на страницах, когда изменения DOM пнули и загрузили страницу, как это было запланировано, с помощью usercript.