Javascript代码在控制台中工作,但在加载时,因为未定义实际的用户脚本函数

时间:2011-11-19 19:01:07

标签: javascript automation greasemonkey userscripts

请记住,我不知道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 个答案:

答案 0 :(得分:4)

注意:

  1. 如果代码缩进并格式化为易读性,则人们更有可能阅读您的代码。 ;-)查看我对您的问题所做的编辑,并且有很多tools that help with formatting

  2. 回复:setInterval("refresh()"...;不要用引号代码调用setInterval(和类似函数)。它总是很糟糕(不必要地使用eval())并且由于沙箱而导致won't work in Greasemonkey变平。

  3. 同样,有时在定义之前使用的JS将“未定义” - 尤其是在eval情况下。

  4. 不要将含糊不清,常用或保留的单词用作变量或函数名称。 int 特别糟糕,因为大多数人会把它读作“整数”,而且它几乎是所有主流语言中的保留字。

  5. 小心selfwindow个对象。这些在Greasemonkey上下文中具有不同的含义/行为。

  6. javascript中并不总是需要分号,这是真的,但养成了一直使用它们的习惯。它将为您节省未来的悲伤,并使代码更容易理解。

  7. 无论如何,如果代码在控制台上工作,那么这也应该来自脚本:

    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);
    

答案 1 :(得分:0)

使用setInterval和事件处理程序,简而言之,该调用是在Greasemonkey沙箱消失后发生的。

网页加载 - &gt; 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);