处理许多元素的事件 - 优化我的解决方案
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>
我正在构建一个简单的商店网站(只是为了练习),尽管我目前的解决方案有效,但从我读到的内容来看,它并不是最优的,可以通过在父元素上创建事件监听器来改进(这里是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>