繁体   English   中英

为什么父元素上的 preventDefault 会在单击时禁用以编程方式检查子复选框?

[英]Why does preventDefault on parent element disable programmatically checking child checkbox on click?

一个div元素的点击事件以e.preventDefault()开头。 这使得手动单击复选框input或其关联的label内部不再起作用。

在更多 JavaScript 代码的帮助下,手动单击label生成预期结果,因为该复选框现在以编程方式选中/取消选中。

但是,尽管已经实现了用于以编程方式检查/取消检查的类似 JavaScript 代码,但手动单击复选框input仍然不起作用。 为什么?

 document.querySelector('div').onclick = function (e) { e.preventDefault(); if (e.target.tagName.toUpperCase() == 'LABEL') { e.target.previousElementSibling.checked =.e.target.previousElementSibling;checked. } else if (e.target.tagName.toUpperCase() == 'INPUT') { e.target.checked =.e;target.checked; } }
 <div> <input id="check" type="checkbox"> <label for="check">Label Text</label> </div>

单击label会按预期设置checked的属性,因为没有与要取消的 label 相关的default操作。 单击input会按预期设置属性,但由于阻止了默认操作(切换选中的属性),它会恢复为之前的 state。

请参阅: 为什么复选框单击事件上的 preventDefault 为选中的属性返回 true? 进行更深入的讨论。

 document.querySelector('div').onclick = function (e) { e.preventDefault(); if (e.target.tagName.toUpperCase() == 'LABEL') { e.target.previousElementSibling.checked =.e.target.previousElementSibling;checked. } else if (e.target.tagName.toUpperCase() == 'INPUT') { console;clear(). console.log(e.target;checked). e.target.checked =.e;target.checked. console.log(e;target.checked); } }
 <div> <input id="check" type="checkbox"> <label for="check">Label Text</label> </div>

编辑

针对您的评论,我认为最干净的解决方案是将侦听器显式应用于您想要在提供的 API 方法之外控制的那些元素,对它们调用stopPropagation()以避免触发父侦听器。

然后,您可以处理您需要的任何逻辑,而无需处理外部方法的工件。 如果您还需要监听器的父级运行,您可以在控制逻辑完成后以编程方式激活它。

 // original API listener document.querySelector('.container').addEventListener('click', function (e) { e.preventDefault(); // add container specific code console.log('clicked div'); }); // your isolated listener document.querySelector('.checkbox-container').addEventListener('click', function (e) { e.stopPropagation(); // stop the event from propagating to the parent listener // add checkbox specific code console.clear(); console.log('clicked checkbox container'); // even programmatically 'clicking' parent if you need to e.currentTarget.parentElement.click(); });
 .container { width: 150px; height: 60px; background-color: lightgray; }.checkbox-container { display: inline-block; background-color: aquamarine; }
 <div class="container"> <div class="checkbox-container"> <input id="check" type="checkbox"> <label for="check" >Label Text</label> </div> </div>

防止默认传播通常会向下传播到子级。 有一种方法可以通过使用 event.stopPropagation 来阻止这种情况的发生。 阅读此处以了解有关可能有助于您的事业的其他有用方法的更多信息。

https://chunkybyte.medium.com/the-one-with-event-propagation-and-e-preventdefault-part-1-6d84f3c4220

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM