JS中如何解决for循环中的延迟执行问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS中如何解决for循环中的延迟执行问题相关的知识,希望对你有一定的参考价值。

参考技术A

我们先来看一个例子
在JS方法里面设置一个for循环,输出每次循环的值,如下图

我们可以根据闭包的知识来更改一下for循环中的逻辑,利用闭包将i的值传递给a

这次在运行程序我们就可以看到输出内容是0开始输出了

结果如下图

JS中如果for循环中有异步方法,就需要用闭包的方式保留当前循环变量值

js中for循环中的addEventListener

【中文标题】js中for循环中的addEventListener【英文标题】:addEventListener in a for loop in js 【发布时间】:2021-12-03 01:31:27 【问题描述】:

我正在尝试在答案块上创建一个 for 循环,我想让答案的高度为 30px 我尝试将事件添加到块中,但它不起作用我,那为什么?

这是我的解决方案:

HTML 代码:

<div class="blocks block-1">
    <div class="questionContainer">
        <div class="questions">How many team members can I invite?</div>
        <div class="answers">
            You can invite up to 2 additional users on the Free plan. There is
            no limit on team members for the Premium plan.
        </div>
    </div>
</div>
<div class="blocks block-2">
    <div class="questionContainer">
        <div class="questions">What is the maximum file upload size?</div>
        <div class="answers">
            No more than 2GB. All files in your account must fit your allotted
            storage space.
        </div>
    </div>
</div>

JavaScript 代码:

const block = document.getElementsByClassName(".blocks");
const answers = document.getElementsByClassName(".answers");

for (i = 0; i < block.length; i++) 
    block[i].addEventListener("click", () => 
        answers[i].style.height = "30px";
    );

【问题讨论】:

@Terry 你错了! toggle 是原生事件 -> ***.com/questions/16751345/… 如果您现在可以更好地理解,我编辑了这个问题.. +我尝试使用“点击”事件,但也没成功 哦,所以我也需要为它添加一个 for 循环吗?或做出类似的回答[i]? @ADyson 在 Terry 发表评论时,PO 对元素的性质表示怀疑。此时很可能是&lt;details&gt; 【参考方案1】:

answers也是一个集合(就像block一样),所以不能直接在上面设置样式。但是对于您的情况,无论如何查看整个系列并没有多大意义。

如果您想在切换块内的answers 元素上设置样式,您需要专门选择它。

同样,toggle 事件仅适用于&lt;details&gt; 元素。解决此问题的标准方法是改为处理“单击”事件,并使用 classList.toggle() 函数在元素上打开和关闭类。

演示:

const blocks = document.querySelectorAll(".blocks");

for (i = 0; i < blocks.length; i++) 

  blocks[i].addEventListener("click", function(e) 
      let answer = this.querySelector(".answers");
      answer.classList.toggle("hidden");
  );
.answers

  height:30px;


.hidden

 display:none;
<div class="blocks block-1">
  <div class="questionContainer">
    <div class="questions">How many team members can I invite?</div>
    <div class="answers hidden">
      You can invite up to 2 additional users on the Free plan. There is no limit on team members for the Premium plan.
    </div>
  </div>
</div>
<div class="blocks block-2">
  <div class="questionContainer">
    <div class="questions">What is the maximum file upload size?</div>
    <div class="answers hidden">
      No more than 2GB. All files in your account must fit your allotted storage space.
    </div>
  </div>
</div>

【讨论】:

哦,谢谢,我会试试的……我在我的问题中编辑了代码,你能看到它并解释为什么它还不能工作吗? 那么你从编辑过的代码中得到了什么结果呢?你做了什么调试?很难说它有什么效果,因为我看不到每个答案上已经设置了哪些 CSS/样式规则 哦,我首先在块上循环,当用户单击块[i]时,我希望答案变成高度:0px 到高度:30px,然后它将显示给用户 所以我使用 answer[i] 因为它将是 block[i] 问题的正确答案 但是没有用...你的方法更好,但我只想知道为什么我的方法不起作用【参考方案2】:

我猜你正在寻找这个结果?

const All_blocks = document.querySelectorAll('.blocks');

All_blocks.forEach( blk =>
  
  blk.addEventListener('click', () =>
    
    blk.classList.toggle('show_answer')
    )
  )
.blocks 
  margin  : .5em;
  padding : .3em;
  
.questions 
  color  : darkblue;
  cursor : pointer;
  
.blocks .answers  
  visibility: hidden;
  
.blocks.show_answer .answers 
  visibility: visible;
  
<div class="blocks block-1">
  <div class="questionContainer">
    <div class="questions">How many team members can I invite?</div>
    <div class="answers">
      You can invite up to 2 additional users on the Free plan. 
      There is no limit on team members for the Premium plan.
    </div>
  </div>
</div>
<div class="blocks block-2">
  <div class="questionContainer">
    <div class="questions">What is the maximum file upload size?</div>
    <div class="answers">
      No more than 2GB. All files in your account must fit your 
      allotted storage space.
    </div>
  </div>
</div>

【讨论】:

【参考方案3】:

首先要使用 DOM 事件,在 NODE 中添加 classList 切换。您必须区分 Dom 事件和 Dom 样式。我在 w3schools 中找不到 DOM 事件切换。 https://www.w3schools.com/jsref/dom_obj_event.asp

编辑: 我为您尝试使用 console.log(blocks) document.getElementsByClassName(".blocks")。 DOM 节点有 2 个类和结果 HTMLCollection emty。您必须使用 querySelectorAll

【讨论】:

这更像是一个评论而不是一个答案。它并没有真正提供解决方案,甚至没有对问题提供特别清晰的解释。获得 50 声望后,您可以添加 cmets。 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于JS中如何解决for循环中的延迟执行问题的主要内容,如果未能解决你的问题,请参考以下文章

js中for循环里面有异步请求怎么解决

Javascript:如何在执行 javascript 代码之间设置一个简单的延迟?

JS实现停留几秒sleep,Js中for循环的阻塞机制,setTimeout延迟执行

如何延迟 For 循环直到声音在 Swift 中播放完毕

如何重试 Promise 解决 N 次,尝试之间有延迟?

Oracle 延时执行问题求指教: