-1

我有一个带有几个下拉列表的网站。当在一个下拉列表中选择一个值时,该站点会运行一个 JavaScript 代码来更改其他下拉列表中的选项。

(例如:我在第一个列表中选择了一个国家,它下面的下拉列表中填充了该国家的城市列表)。

这不是我的网站。我正在尝试创建一个 Greasemonkey 脚本,将值填充到这些下拉列表中。我可以使用这个 jQuery 命令来模拟选项的选择。

$('select[id="dropdown1"]').val("GBR").trigger('change');

这工作正常。它选择顶部下拉列表中的值。但是,不在其他人中,因为它们尚未包含我发送到那里的值。

我希望根据我的选择填充其他下拉列表,但这在我的脚本结束之前不会发生。换句话说,在网站上运行并填充下拉列表的脚本等待我的脚本结束。

我想要实现的是暂停我的脚本,允许网站脚本运行,然后继续我的脚本。换句话说,让网站脚本优先执行。

我尝试使用 setTimeout 但这没有用。它甚至停止更改顶部下拉列表值。

setTimeout(function() {
    $('select[id="dropdown1"]').val("GBR").trigger('change');
}, 3000);

知道如何暂停我的脚本,让其他人执行然后继续运行我的脚本吗?

4

1 回答 1

0

它可以与 一起使用setTimeout,但您不应将“GBR”选择放在其回调中——您仍想立即执行该部分。而是将其他代码放在那里,这将检查是否已填充第二个列表,如果已填充,则使用它执行您打算执行的任何操作。

这是一些代码,其中“现有页面”是用一些虚拟 Ajax 服务器模拟的,该服务器提供一些拉丁词作为响应并用于填充第二个列表框:

// Script already on the page -- you can ignore this bit
$("#dropdown1").change(function() {
    $.get("https://jsonplaceholder.typicode.com/posts/" + (this.selectedIndex+1)).then(function (response) {
        $("#dropdown2").empty().append(
            $.map(response.body.split(" "), function (txt) {
                return $("<option>").text(txt)
            })
        );
    });
});

// Your GreaseMonkey script:
$("#dropdown2").empty(); // really empty this, so you can detect when it is populated
$('#dropdown1').val("GBR").trigger('change');
setTimeout(function loop() {
    if ($("#dropdown2>option").length) {
        console.log('change detected');
        return;
    }
    // Keep trying
    setTimeout(loop, 50);
}, 50);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="dropdown1">
    <option>Norway</option>
    <option>Jemen</option>
    <option>Kenya</option>
    <option>GBR</option>
</select>
<select id="dropdown2">
</select>

请注意如何在页面加载时选择 GBR 值,并且控制台输出已检测到第二个框中的更改。第二位发生在setTimeout回调中。

于 2017-12-02T22:11:20.230 回答