Javascript代码在控制台中工作,但是当作为实际的userscript函数加载时没有定义

Javascript code works in console, but when loaded as actual userscript functions are not defined

本文关键字:userscript 函数 加载 定义 控制台 代码 工作 Javascript      更新时间:2023-09-26

请记住,我不知道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);
}

如果将其直接粘贴到控制台中,它将按预期工作,按刷新按钮直到满足条件,然后按Join按钮。作为用户脚本安装,我从Chrome和Firebug中得到以下错误:

Uncaught ReferenceError: refresh is not defined
(anonymous function)

每隔四秒返回一次。

关于用户脚本有什么我不知道的吗?我做错了什么?

备注:

  1. 人们更有可能阅读你的代码,如果它是缩进和格式化的易读性。-)看看我对你的问题所做的编辑,有很多工具可以帮助格式化。

  2. Re: setInterval("refresh()"...;不要用这样的引号代码调用setInterval(和类似的函数)。它总是很差的形式(不必要地使用eval()),它的平坦不会在Greasemonkey工作,由于沙盒。

  3. 同样,有时JS在定义之前使用将是"未定义"-特别是在eval情况下。

  4. 不要使用有歧义的、通用的或保留的词作为变量名或函数名。int尤其糟糕,因为大多数人会把它读成"Integer",几乎在所有主流语言中它都是保留字。

  5. 小心selfwindow对象。这些在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);

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