我有一个包含几个下拉列表的网站。在一个下拉列表中选择值后,该站点将运行一个javascript代码,用于更改其他下拉列表中的选项。
(示例:我在第一个列表中选择一个国家/地区,其下方的下拉列表中填充了该国家/地区的城市列表)。
这不是我的网站。我正在尝试创建一个Greasemonkey脚本,它将填充这些下拉列表的值。我可以使用这个jQuery命令模拟选项的选择。
$('select[id="dropdown1"]').val("GBR").trigger('change');
这很好用。它选择顶部下拉列表中的值。但不是在其他人中,因为他们还没有包含我寄给我们的价值观。
我希望根据我的选择填充其他下拉列表,但在脚本结束之前不会发生这种情况。换句话说,在网站上运行并填充下拉列表的脚本会等待我的脚本结束。
我想要实现的是暂停我的脚本,允许网站脚本运行然后继续我的脚本。换句话说,给网站脚本优先执行。
我尝试过使用setTimeout,但是没有用。它甚至会停止更改顶部下拉列表值。
setTimeout(function() {
$('select[id="dropdown1"]').val("GBR").trigger('change');
}, 3000);
知道如何暂停我的脚本,让别人执行然后继续运行我的脚本吗?
答案 0 :(得分: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
回调中。