如何解决click事件不适用于内部标记元素 演示演示替代解决方案演示
这是我正在使用的标记
<div class="checkout-row__form-column__billing">
<div class="checkout-row__form-column__billing__title billing-collapse collapse-btn">
<div class="checkout-row__form-column__billing__title__arrow">
<i class="fa fa-chevron-right" aria-hidden="true"></i>
</div>
<h2>1. Billing Details</h2>
</div>
<div class="checkout-row__form-column__shipping__content shipping-collapse-content collapse-target"></div>
<div class="checkout-row__form-column__shipping">
<div class="checkout-row__form-column__shipping__title shipping-collapse collapse-btn">
<div class="checkout-row__form-column__shipping__title__arrow">
<i class="fa fa-chevron-right" aria-hidden="true"></i>
</div>
<h2>2. Shipping Details</h2>
</div>
<div class="checkout-row__form-column__shipping__content shipping-collapse-content collapse-target"></div>
所有这些标记都以div
类包装在checkout-row__form-column
中。
因此,我要抓住父包装器,单击“目标与.collapse-btn
匹配”。然后在同级.collapse-target
上进行类切换。除了在问题上我无法超越之外,效果很好。如果单击内部元素,则事件不会发生。
这是我的js
parent = document.querySelector('.checkout-row__form-column');
parent.addEventListener('click',(e)=>{
if (e.target.matches('.collapse-btn')) {
e.stopPropagation();
e.target.nextElementSibling.classList.toggle('hide');
}
});
使用这些代码,如果我不单击i
元素或h2
,就可以切换类。如果我单击e.target
内的任意位置,该如何触发该事件,我该如何编写JavaScript。
任何帮助都是同志们的赞赏。
解决方法
您的代码仅检查event.target
是否为.collapse-btn
元素。您还需要检查clicked元素是否是.collapse-btn
元素的后代元素。
要获得所需的结果,可以使用两个条件来检查event.target
是.collapse-btn
还是其任何后代。要检查后代元素,请使用通用选择器*
。
parent.addEventListener('click',(e) => {
if (
e.target.matches('.collapse-btn') ||
e.target.matches('.collapse-btn *')
) {
// code
}
});
演示
以下代码段显示了一个示例:
const parent = document.querySelector('.container');
parent.addEventListener('click',e => {
if (
e.target.matches('.collapse-btn') ||
e.target.matches('.collapse-btn *')
) {
parent.classList.toggle('active');
}
});
.container {
background: #eee;
width: 120px;
height: 120px;
}
.container.active {
border: 2px solid;
}
.collapse-btn {
background: #999;
padding: 10px;
}
.collapse-btn span {
background: #fc3;
font-size: 1.3rem;
cursor: pointer;
}
<div class="container">
<div class="collapse-btn">
<span>Click</span>
</div>
</div>
您还可以将选择器放入数组中,然后使用.some()
方法检查event.target
是否与数组中的选择器匹配。
const selectors = ['.collapse-btn','.collapse-btn *'];
parent.addEventListener('click',e => {
if (selectors.some(s => e.target.matches(s))) {
// code
}
});
演示
以下代码段显示了一个示例:
const parent = document.querySelector('.container');
parent.addEventListener('click',e => {
const selectors = ['.collapse-btn','.collapse-btn *'];
if (selectors.some(s => e.target.matches(s))) {
parent.classList.toggle('active');
}
});
.container {
background: #eee;
width: 120px;
height: 120px;
}
.container.active {
border: 2px solid;
}
.collapse-btn {
background: #999;
padding: 10px;
}
.collapse-btn span {
background: #fc3;
font-size: 1.3rem;
cursor: pointer;
}
<div class="container">
<div class="collapse-btn">
<span>Click</span>
</div>
</div>
替代解决方案
不是使用.matches()
方法,而是使用Element.closest()
和Node.contains()
方法的组合来检查event.target
是.collapse-btn
元素还是A { .collapse-btn
元素的子元素。
要执行此操作,您需要执行两个步骤:
-
您首先需要获取
.collapse-btn
的最接近祖先的event.target
。 -
之后,您需要检查
event.target
是否是在步骤1中选择的按钮的后代。
代码:
parent.addEventListener('click',(e) => {
const targetCollapseBtn = e.target.closest('.collapse-btn');
if (targetCollapseBtn && targetCollapseBtn.contains(e.target)) {
...
}
});
如果event.target
本身就是.collapse-btn
,那么
e.target.closest('.collpase-btn')
将返回e.target
,即.collapse-btn
和
targetCollapseBtn.contains(e.target)
还将返回true,因为.contains()
方法返回true,即使作为参数传递给它的节点与调用.contains()
方法的节点位于同一节点。
因此,以这种方式使用.closest()
和.contains()
方法可以同时涵盖两种使用情况,即单击.collapse-btn
或单击其任何后代元素时。
演示
以下代码段显示了一个简单的示例:
const parent = document.querySelector('.container');
parent.addEventListener('click',e => {
const targetCollapseBtn = e.target.closest('.collapse-btn');
if (targetCollapseBtn && targetCollapseBtn.contains(e.target)) {
parent.classList.toggle('active');
}
});
.container {
background: #eee;
width: 120px;
height: 120px;
}
.container.active {
border: 2px solid;
}
.collapse-btn {
background: #999;
padding: 10px;
}
.collapse-btn span {
background: #fc3;
font-size: 1.3rem;
cursor: pointer;
}
<div class="container">
<div class="collapse-btn">
<span>Click</span>
</div>
</div>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。