【问题标题】:Swap DOM Elements with Timeout使用超时交换 DOM 元素
【发布时间】:2021-05-06 21:56:55
【问题描述】:

我目前正在尝试学习 JavaScript。 (香草) 所以目前我想做的是交换不同的元素节点。 例如,想象一个包含不同条目的列表,稍后将交换它们。

为此,element.length 次应交换随机元素。每次交换后都应该超时。

我现在遇到的问题是列表只有在 shuffle 函数完成后才会更新。

打算交换一对,等待1秒再进行下一次交换。

function shuffle(element){
    disableButtons();
    let clicked_elmnt = document.getElementsByTagName(element);
    console.log(clicked_elmnt);
    if(clicked_elmnt.length !== 1 && clicked_elmnt !== 0){
        for (let i = 0; i<clicked_elmnt.length;++i){
            setTimeout(function(){doIt(element,randomNumber(clicked_elmnt.length),randomNumber(clicked_elmnt.length))}, 1000)
        }
    }
    enableButtons();
} 

此代码应检查列表中是否存在列表,然后在尝试将父级与子级交换时滚动新数字。 (似乎有效)

function doIt(element,first,second){
        let clicked_elmnt = document.getElementsByTagName(element);

        if(clicked_elmnt[first].children.length > 0){
            if(clicked_elmnt[first].firstElementChild.isSameNode(clicked_elmnt[second].parentNode)){
                doIt(element,randomNumber(clicked_elmnt.length),randomNumber(clicked_elmnt.length));
            }else{
                if(clicked_elmnt[second].children.length > 0){
                    if(clicked_elmnt[second].firstElementChild.isSameNode(clicked_elmnt[first].parentNode)){
                        doIt(element,randomNumber(clicked_elmnt.length),randomNumber(clicked_elmnt.length));
                    }else{
                        doSwap(clicked_elmnt[first],clicked_elmnt[second]);
                    }
                }else{
                    doSwap(clicked_elmnt[first],clicked_elmnt[second]);
                }
            }   
        }else{
            if(clicked_elmnt[second].children.length > 0){
                if(clicked_elmnt[second].firstElementChild.isSameNode(clicked_elmnt[first].parentNode)){
                    doIt(element,randomNumber(clicked_elmnt.length),randomNumber(clicked_elmnt.length));
                }else{
                    doSwap(clicked_elmnt[first],clicked_elmnt[second]);
                }
            }else{
                doSwap(clicked_elmnt[first],clicked_elmnt[second]);
            }
        }
    }

然后交换发生在下一个函数中。在这里它们被交换了。

function doSwap(n1, n2){
    console.log("swap");
    const afterN2 = n2.nextElementSibling;
    const parent = n2.parentNode;
    if (n1 === afterN2) {
        parent.insertBefore(n1, n2);
      } else {
        n1.replaceWith(n2);
        parent.insertBefore(n1, afterN2);
      }   
}

希望有人能在没有那么多奇怪的东西的情况下帮助我。 干杯!

【问题讨论】:

  • 请生成minimal reproducible example。您的描述令人困惑,因为您说“每次交换都应该超时。”但是您的超时发生了,然后您致电doSwap()。这与你描述的相反。至于shuffle() 函数提前结束,这就是异步代码的工作方式。超时将最终发生(可能在 1 秒后),但那是在其余代码完成执行之后很久。

标签: javascript dom dom-events


【解决方案1】:

我的理解是您希望doIt 调用,setTimeout 的回调彼此相隔 1 秒。 setTimeout 的工作方式是回调排队等待在调用 setTimeout 后 x 毫秒执行。如果您希望在前一个函数完成后 1 秒调用一个函数,您可以从回调内部调用另一个 setTimeout

这是您的示例调整为 - doItLater 函数包含一个 setTimeout 调用,并将递归调用自身 clicked_elmnt.length 次。您可能可以针对实际场景进行更干净的设置,但这很合适,不会与您的示例有太大的偏差。

function shuffle(element) {
  disableButtons();
  let clicked_elmnt = document.getElementsByTagName(element);
  if (clicked_elmnt.length !== 1 && clicked_elmnt !== 0) {
    const doItLater = function (i) {
      setTimeout(() => {
        doIt(element, randomNumber(clicked_elmnt.length), randomNumber(clicked_elmnt.length));
        
        if (i + 1 < clicked_elmnt.length) {
          doItLater(i + 1);
        }
      }, 1000);
    }
    doItLater(0);
  }
  enableButtons();
}

如果您只想在最后一个 doIt 调用完成后调用 enableButtons,您可以将该调用移至 if (i + 1 &lt; clicked_elmnt.length)else 子句。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多