【问题标题】:how does forEach works in this case?在这种情况下,forEach 是如何工作的?
【发布时间】:2020-12-09 03:06:47
【问题描述】:

我有 2 个按钮,它们激活/停用 div,按钮下一个激活下一个 div,按钮 prev 停用当前 div。 每次点击都会调用函数更新,我试图了解在这种情况下比较数组的索引和 currentActive 如何帮助我们。 我注释掉其余代码以遵循 idx 的值,但我对输出感到困惑......................

const progress = document.getElementById('progress');
const prev = document.getElementById('prev');
const next = document.getElementById('next');
const circles = document.querySelectorAll('.circle');
let currentActive = 1;

next.addEventListener('click', () => {
  currentActive++;
  if (currentActive > circles.length) {
    currentActive = circles.length;
  }
  update();
});

prev.addEventListener('click', () => {
  currentActive--;
  if (currentActive < 1) {
    currentActive = 1;
  }

  update();
});

function update() {
  console.log(' - - - - - - - - ')    
  console.log('update function, currentActive = '+ currentActive )
  
  circles.forEach((circle, idx) => {

    console.log('idx->'+ idx + ', ==Active?->' + (idx===currentActive) + ', div->' + circle.textContent )

    
   // if (idx < currentActive) {
   //   console.log('index is:' + idx, 'current is :' + currentActive);

    // circle.classList.add('active');
     // }
    /* else {
            circle.classList.remove('active');
        }
    });

    if (currentActive === 1) {
        prev.disabled = false;
    } else if (currentActive === circles.length) {
        next.disabled = true;
        prev.disabled = false;
    } else {
        prev.disabled = false;
        next.disabled = false;
    } */

  });
}
.as-console-wrapper { 
  top        : 0;
  left       : 30%  !important;
  max-height : 100% !important;
  width      : 70%;
  }
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" integrity="sha512-+4zCK9k+qNFUR5X+cKL9EIR+ZOhtIloNl9GIKS57V1MyNsYpYcUrUeQc9vNfzsWfV28IaLL3i96P9sdNyeRssA==" crossorigin="anonymous" />
  <link rel="stylesheet" href="style.css" />

  <title>Progress Steps</title>
  <div class="container">
    <div class="progress-container">
      <div class="progress" id="progress"></div>
      <div class="circle active">1</div>
      <div class="circle">2</div>
      <div class="circle">3</div>
      <div class="circle">4</div>
    </div>
    <button class="btn" id="prev" disabled>Prev</button>
    <button class="btn" id="next">Next</button>
  </div>
</head>

<body>
  <script src="script.js"></script>
</body>

</html>

【问题讨论】:

  • 它遍历所有具有包含circle的类的元素
  • 如果你的意思是类圈,控制台日志的输出应该是数组的4个元素,为什么只有2个? idx开头的值是多少?
  • 你有一个条件......所以,不,它不仅仅是 2......它是 2,然后是 3,然后是 4,当你点击下一步时 - 你的条件意味着 console.log 不会一直运行迭代,但每次迭代都在运行
  • @Bravo 有 for 循环背景让我感到困惑。如果我错了,请纠正我:forEach 没有计数器,它通过数组并根据应用的条件显示输出。对吗?
  • 就像你用英语说的。对于圆圈中的每个圆圈,请执行此操作(函数的主体)。你不能在这里使用for 循环,因为circles 不是一个实际的数组,而是一个NodeList。但是,您可以使用 Array.from(circles) 将其转换为数组。

标签: javascript foreach


【解决方案1】:

“……我试图了解在这种情况下比较数组的索引和 currentActive 如何帮助我们。”

认为你的第一个 idx 是 0,然后加载你的 currentActive=1 然后你的条件是如果 idx&lt;currentActive ,它将收到一个类 active

现在看看当你点击下一个时会发生什么, 由于您的 currentActive 是 1 onload,当您单击 next 时会发生 currentActive++ 导致 2,现在查看您的条件,如果 idx&lt;currentActive(这次 idx 为 1)并且条件为真,因此它将收到一个类active,但上一个将删除类active(并且每次单击它都会根据您的条件重置值)......。现在查看您的其他代码并尝试理解 prev click 和其他代码。

【讨论】:

    【解决方案2】:

    我认为困扰你的是在计算中,列表的第一个索引为零。

    这是您的代码(重新访问)

    const progress     = document.getElementById('progress')
        , bt_prev      = document.getElementById('prev')
        , bt_next      = document.getElementById('next')
        , divs_circle  = document.querySelectorAll('.circle')
        , Last_circle  = divs_circle.length -1
        , progressText =
           [ 'payment first step'
           , 'payment second step'
           , 'payment third step'
           , 'payment last step'
           , 'payment done !'
           ]
        ;
    var currentActive = 0  // the first index is zero 
      ;
    function setActivCircle()
      {
      divs_circle.forEach((circle, idx )=>
        {
        if ( idx === currentActive ) circle.classList.add('active')
        else                         circle.classList.remove('active')
    
        if( idx < currentActive ) circle.classList.add('done')
        else                      circle.classList.remove('done')
        })
      progress.textContent = progressText[currentActive] 
      bt_prev.disabled     = (currentActive === 0) || (currentActive > Last_circle)
      bt_next.disabled     = (currentActive > Last_circle)
      bt_next.textContent  = (currentActive === Last_circle) ? 'Terminate' : 'Next'
      
      console.clear()
      console.log(`currentActive value is ${currentActive}, last Idx value is ${Last_circle}`)
      }
    setActivCircle() // first attempt
    
    bt_next.onclick = () =>
      {
      ++currentActive 
      setActivCircle()
      }
    bt_prev.onclick = () =>
      {
      --currentActive
      setActivCircle()
      }
    div.circle {
      padding : .2em;
      width   : 5em;
      border  : 1px solid grey;
      margin  : .2em;
      }
    div.active {
      background-color : lightblue;
      }
    div.done {
      background-color : lightgreen;
      }
    <div class="container">
      <div class="progress-container">
        <div class="progress" id="progress"></div>
        <div class="circle" >1</div>
        <div class="circle" >2</div>
        <div class="circle" >3</div>
        <div class="circle" >4</div>
      </div>
      <button class="btn" id="prev" > Prev</button>
      <button class="btn" id="next" > Next</button>
    </div>

    【讨论】:

    • 您的代码为此目的而工作,但我提到的代码使之前的数字保持活动状态。将其视为在线支付过程..Step on active,然后第 2 步处于活动状态..等等
    • prev 按钮无法正常工作,但我有正确的代码,只是想理解它。
    • 您的代码仍然有问题,按钮在最后停用。代码本身对我来说不是问题,forEach 和里面的条件是我的主要困惑。
    • @bigly 您告诉我将此理解为付款的步骤,因此在付款完成后停用所有内容对我来说似乎更合乎逻辑。我更改了文本以显示
    • @bigly 在我看来,您仍然不明白forEach 的工作原理。我添加了一个 console.log 来显示 2 个索引值,希望对您有所帮助。
    猜你喜欢
    • 2020-08-20
    • 1970-01-01
    • 2016-12-05
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    • 2023-02-04
    • 2018-06-16
    • 2017-06-21
    相关资源
    最近更新 更多