处理许多元素的事件 - 优化我的解决方案

Handling Events for Many Elements - optimalizing my solution

我正在构建一个简单的商店网站(只是为了练习),尽管我目前的解决方案有效,但从我读到的内容来看,它并不是最优的,可以通过在父元素上创建事件监听器来改进(这里是cart-items 而不是在每个锚元素上。问题是,当我将事件处理程序附加到它时,如果篮子中有两个或更多元素,则只有第一个输入被更改,无论我单击哪个增加按钮(来自产品一、二等的那个)。

我的问题是:在这种情况下,将事件侦听器附加到父元素确实是最好的选择,如果是,我如何才能正确重构我的代码以使 increase/decrease 按钮在最接近的输入值上工作,不仅在呈现列表中的第一个? 下面附上我目前的 JS 代码:

const qtyBoxes = document.querySelectorAll('.cart-qty-box');

    qtyBoxes.forEach((box) => {
    
        const increase = box.querySelector('.increase');
        const decrease = box.querySelector('.decrease');
        const currQty = box.querySelector('.currQty');
        
        increase.addEventListener('click', function(e) {
            e.preventDefault();
            currQty.value++;

            $('#przelicz').click(); //uptades UI
        });
        
        decrease.addEventListener('click', function(e) {
            e.preventDefault();
            if(currQty.value > 0) { 
               currQty.value--;
            }


            $('#przelicz').click(); //updates UI
        });
        
       
        });

HTML:

<div class="cart-items">
///... Item 1 code ...

    <div class="qty-box">
       <div class="qty-ctl">
          <a class="incr-btn decrease" data-action="decrease" href="#"></a> 
       </div> 
       <input id="qnt" class="qty currQty input-text" type="text" value="{$poz->count}"/> 
       <div class="qty-ctl"> 
          <a class="incr-btn increase" data-action="increase" href="#"></a> 
       </div>
    </div>
///... Item 2 code ...

    <div class="qty-box">
       <div class="qty-ctl">
          <a class="incr-btn decrease" data-action="decrease" href="#"></a> 
       </div> 
       <input id="qnt" class="qty currQty input-text" type="text" value="{$poz->count}"/> 
       <div class="qty-ctl"> 
          <a class="incr-btn increase" data-action="increase" href="#"></a> 
       </div>
    </div>
</div>

如果对我要构建的内容的描述不清楚,我会在此处将 link 粘贴到图像中: screenshot of basket

是的,最好将事件侦听器附加到父级,因为您只有一个侦听器而不是多个侦听器(每个按钮一个)。


您可以通过检查 click 事件 (e.target) 的目标属于哪个框来实现:

const click_parent = e.target.closest('.qty-box');

如果是增加或减少按钮,例如:

if (e.target.classList.contains('increase')) {

其余部分与您的代码段中的一样。

工作示例:

document.querySelector('.cart-items').addEventListener('click', function(e) {

  e.preventDefault();
  const click_parent = e.target.closest('.qty-box');
  const currQty = click_parent.querySelector('.currQty');

  if (e.target.classList.contains('increase')) {
    currQty.value++;

    $('#przelicz').click(); //uptades UI
  } else if (e.target.classList.contains('decrease')) {
    if (currQty.value > 0) {
      currQty.value--;
    }

    $('#przelicz').click(); //uptades UI    
  }

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="cart-items">
  ///... Item 1 code ...

  <div class="qty-box">
    <div class="qty-ctl">
      <a class="incr-btn decrease" data-action="decrease" href="#">decrease</a>
    </div>
    <input id="qnt" class="qty currQty input-text" type="text" value="2" />
    <div class="qty-ctl">
      <a class="incr-btn increase" data-action="increase" href="#">increase</a>
    </div>
  </div>
  ///... Item 2 code ...

  <div class="qty-box">
    <div class="qty-ctl">
      <a class="incr-btn decrease" data-action="decrease" href="#">decrease</a>
    </div>
    <input id="qnt" class="qty currQty input-text" type="text" value="3" />
    <div class="qty-ctl">
      <a class="incr-btn increase" data-action="increase" href="#">increase</a>
    </div>
  </div>
</div>