【问题标题】:How to make for loop wait for an element before moving to next iteration如何让 for 循环在移动到下一次迭代之前等待一个元素
【发布时间】:2019-11-29 16:50:52
【问题描述】:

我有一个带有 xpaths 数组的 for 循环,它选择按钮元素并在选择框中选择一个选项。这应该针对每个数组项一一发生。我的代码或多或少可以工作,但如果元素为空,则不等待选项元素。我希望 for 循环尝试查找元素,直到找到它,然后再执行 for 循环中的其余代码并移动到下一次迭代。

case = ["xpath1", "xpath2", "xpath3", "xpath4"];

function loopThroughArray(case) {
    for (var i = 0; i <case.length; i++) {
        (function(i) {
            setTimeout(function() {
                //start - getting the corresponding elements and clicking it
                var dt_links = document.evaluate(case[i], document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
                var dtLinks = dt_links.snapshotLength;
                if (dtLinks != 0) {
                    for (var a = 0; a < dtLinks; ++a) {
                        dt_links.snapshotItem(a).click();
                    }
                    var ex = document.evaluate("//select/optgroup/option[contains(text(),'new item')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
                    var expEl = ex.snapshotItem(0);
                    if (expEl == null) {
                        console.log("new item option is not available");
                    }
                   else{
                    //"new item" option is selected
                    ex.snapshotItem(0).selected = true
                    var exp = $('select')[2] //select box
                    console.log(exp)
                    if ("createEvent" in document) {
                        var evt = document.createEvent("HTMLEvents");
                        evt.initEvent("change", false, true);
                        exp.dispatchEvent(evt);
                    } else {
                        exp.fireEvent("onchange");
                        console.log("change event to be fired");
                    }
               }
                }
            }, 1500 * i);
        })(i);
    };
}
loopThroughArray(case);

所以基本上,我需要遍历数组,选择一些按钮元素并在选择框中选择一个选项,等待 iframe 加载并填充选择框及其选项,然后再选择下一组按钮迭代等等。

【问题讨论】:

  • "selecting" 是指用户正在触发change 事件还是以编程方式完成?
  • 抱歉不清楚,是的,我的意思是使用特定选项触发更改事件

标签: javascript jquery for-loop


【解决方案1】:

SetTimeout 使您的代码立即返回,因此几乎同时启动所有超时。

我相信你可以通过创建递归函数而不是 for 循环来实现你想要的:

var recursiveFunc = function(i) {
        setTimeout(function() {
            ...
            if(i < case.lenght - 1){
                 recursiveFunc(i++)
            }
        }, 1500 * i);
    })(0)

编辑根据 cmets,似乎你无法耗尽堆栈,即使你的数组​​太长。

【讨论】:

  • setTimeout 基本上是开始一个新的堆栈,所以你不会在这里遇到溢出问题。
  • 这很好:)。
  • 嗨,pablo,感谢您的建议,但我仍然得到空元素,函数不等待元素
  • 好吧,也许您使用保留字 case 作为变量这一事实与您的错误有关
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多