Как запустить скрипт greasemonkey до отображения содержимого страницы? - PullRequest
24 голосов
/ 12 февраля 2011

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

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

Ответы [ 3 ]

26 голосов
/ 02 июля 2011

РЕДАКТИРОВАТЬ: Это сообщение было создано до реализации ключа @run-at в Greasemonkey - как было отмечено Блезом, из Greasemonkey 0.9.8 теперь вы можете запустить скрипт, как только страница начнет загружаться.

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

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

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

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

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



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

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

Это то, чего давно хотелось, и просматривая выпуск # 1103 на сайте Greasemonkey's Github, работающемПрототип, кажется, был сделан (но нет никакой временной шкалы для этого, чтобы быть добавленным к версии выпуска afaik).

2 голосов
/ 19 июля 2017

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

// @run-at      document-start

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

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

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

2 голосов
/ 11 марта 2016

Используя @run-at document-start, как предложено в ответе @kwah, мой скрипт выполнялся до того, как содержимое, которым я хотел манипулировать, находилось в теле документа. В качестве обходного пути я установил интервал выполнения сценария 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);

}
...