为了账号安全,请及时绑定邮箱和手机立即绑定

单击事件不适用于内部标记元素

单击事件不适用于内部标记元素

qq_花开花谢_0 2023-05-11 16:05:55
这是我正在使用的标记<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。效果很好,除了问题,我无法通过。如果我单击内部元素,则事件不会发生。这是我的jsparent = document.querySelector('.checkout-row__form-column');    parent.addEventListener('click', (e)=>{      if (e.target.matches('.collapse-btn')) {        e.stopPropagation();                e.target.nextElementSibling.classList.toggle('hide');      }    });使用这些代码,如果我不单击ielement 或 ,我就可以切换类h2。我如何编写我的 JavaScript,如果我点击e.target.同志们非常感谢任何帮助。
查看完整描述

1 回答

?
梦里花落0921

TA贡献1772条经验 获得超5个赞

您的代码仅检查元素是否event.target为.collapse-btn元素。您还需要检查单击的元素是否是该.collapse-btn元素的后代元素。


为了达到预期的结果,您可以使用这两个条件来检查 the 是event.targetthe.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.collapse-btn

为此,您需要执行两个步骤:

  1. 您首先需要获取 the.collapse-btn的最近祖先event.target

  2. 之后,您需要检查 是否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>


查看完整回答
反对 回复 2023-05-11
  • 1 回答
  • 0 关注
  • 91 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信