Javascript-код работает в консоли, но при загрузке как фактический пользовательский скрипт функции не определены - PullRequest
1 голос
/ 19 ноября 2011

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

Я пытаюсь создать скрипт пользователя, который нажимает указанную кнопку на странице через определенные промежутки времени, пока не будет выполнено определенное условие, затем остановите цикл и нажмите другую кнопку.Благодаря некоторой помощи здесь я получил кусок кода, который делает именно то, что я хочу, когда вставляется в консоль Chrome или Firebug.

Однако, если я устанавливаю этот сценарий как расширение Chrome или сценарий Greasemonkey,Я получаю неопределенные ошибки.

var int = self.setInterval ("refresh ()", 4000);

function stop () { 
    // Stop the loop before joining server
    int = window.clearInterval (int)
}

function join () { 
    // Click Join Server button
    document.getElementsByClassName (
        "base-button-arrow-almost-gigantic"
    )[0].click ();
}

function refresh () { 
    // If current players < max, cancel loop and join server
    var playersElement = document.getElementById ('server-info-players');
    var players = playersElement.textContent;
    var parts = players.split ("/");

    var current = parseFloat (parts[0]);
    var max = parseFloat (parts[1]);

    if (current < max) {
        stop ()
        join ()
    }

    var refreshBtn = document.querySelector (
        "div.serverguide-header-refresh-button div[type='reset'] a"
    );
    var clickEvent = document.createEvent ('MouseEvents');
    clickEvent.initEvent ('click', true, true);
    refreshBtn.dispatchEvent (clickEvent);
}

Если он вставлен прямо в консоль, он работает как положено, нажимая кнопку обновления до тех пор, пока условие не будет выполнено, затем нажимая кнопку присоединения.Установленный как пользовательский скрипт, я получаю следующее сообщение об ошибке как от Chrome, так и от Firebug:

Uncaught ReferenceError: refresh is not defined
(anonymous function)

Это просто продолжает возвращаться с интервалами в четыре секунды.

Есть ли что-то в пользовательских скриптах, которые я не делаюзнаете?Что я делаю не так?

Ответы [ 2 ]

4 голосов
/ 20 ноября 2011

Примечания:

  1. Люди с большей вероятностью читают ваш код, если он имеет отступ и отформатирован для удобочитаемости. ;-) Смотрите изменения, которые я сделал к вашему вопросу, и есть множество инструментов, которые помогают с форматированием .

  2. Re: setInterval("refresh()"...; не вызывайте setInterval (и подобные функции) с таким кодом в кавычках. Это всегда плохая форма (использует eval() излишне), и она выровнена не будет работать в Greasemonkey из-за песочницы.

  3. Аналогично, иногда JS, который используется до его определения, будет «не определен» - особенно в eval ситуациях.

  4. Не используйте неоднозначные, общие или зарезервированные слова в качестве имен переменных или функций. int особенно плохо, так как большинство будет читать его как "Integer", и это зарезервированное слово почти во всех основных языках.

  5. Будьте осторожны с объектами self и window. Они имеют разные значения / поведения в контексте Greasemonkey.

  6. Точки с запятой не всегда требуются в javascript, правда, но они имеют привычку всегда их использовать. Это избавит вас от горя в будущем и немного облегчит понимание кода.

В любом случае, если код работал с консоли, то это также должно работать из скрипта:

var refreshInterval;

function stopRefreshTimer () { 
    // Stop the loop before joining server
    clearInterval (refreshInterval);
}

function joinServer () { 
    // Click Join Server button
    document.getElementsByClassName (
        "base-button-arrow-almost-gigantic"
    )[0].click ();
}

function refreshUntilJoiningServer () { 
    // If current players < max, cancel loop and join server
    var playersElement  = document.getElementById ('server-info-players');
    var players         = playersElement.textContent;
    var parts           = players.split ("/");

    var current         = parseFloat (parts[0]);
    var max             = parseFloat (parts[1]);

    if (current < max) {
        stopRefreshTimer ();
        joinServer ();
    }

    var refreshBtn      = document.querySelector (
        "div.serverguide-header-refresh-button div[type='reset'] a"
    );
    var clickEvent      = document.createEvent ('MouseEvents');
    clickEvent.initEvent ('click', true, true);
    refreshBtn.dispatchEvent (clickEvent);
}

refreshInterval         = setInterval (refreshUntilJoiningServer, 4000);
0 голосов
/ 22 января 2012

Как с setInterval, так и с обработчиком событий, в двух словах, этот вызов происходит после того, как песочница Greasemonkey исчезла.

Загрузка страницы -> Greasemonkey запускается, запускает скрипт, Greasemonkey уходит. (Проходит 4 секунды) Ваш сценарий теперь происходит.

Что вам нужно сделать, это передать область действия вместе с setInterval, так что он все еще там, когда эти 4 секунды прошли. Вы можете легко сделать это с помощью анонимной функции. (И в то же время избегайте подразумеваемого eval (), который вы делаете в настоящее время ...)

Грубо говоря, вот как должен выглядеть ваш код:

var notInt = self.setInterval(function () {

    function stopRefreshTimer() {
        // Stop the loop before joining server
        clearInterval(refreshInterval);
    }

    function joinServer() {
        // Click Join Server button
        document.getElementsByClassName("base-button-arrow-almost-gigantic")[0].click();
    }

    // If current players < max, cancel loop and join server
    var playersElement = document.getElementById('server-info-players');
    var players = playersElement.textContent;
    var parts = players.split("/");

    var current = parseFloat(parts[0]);
    var max = parseFloat(parts[1]);

    if (current < max) {
        stopRefreshTimer();
        joinServer();
    }

    var refreshBtn = document.querySelector("div.serverguide-header-refresh-button div[type='reset'] a");
    var clickEvent = document.createEvent('MouseEvents');
    clickEvent.initEvent('click', true, true);
    refreshBtn.dispatchEvent(clickEvent);
}, 4000);
...