Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

冒泡应该借力使力

  去年写过一篇建议不要阻止冒泡的文章,因为踩到了阻止冒泡坑,但当时的解决方案是绕过的那个问题。如果一个阻止冒泡很容易解决问题的场景,我们为了避免阻止冒泡而绕了一大圈,写出一坨难以维护的代码,那也是得不偿失的。所以可不可以直接就利用冒泡机制来解决问题呢?
  一个典型的场景是 dialog,通常 dialog 的交互是点击屏幕上除了某个元素的任何地方都关闭对话框。比如下面这一坨烂代码(只是个 Demo,不要吐槽实现) <div id="dialog"><span id="content">HEHE</span></div> <button id="btn">Open Dialog</button> <style> #dialog { position: fixed; background: rgba(0,0,0,.8); top: 0; left: 0; height: 100%; width: 100%; text-align: center; display: none; } #content { font-size: 64px; padding: 16px 32px; border: 1px solid #ccc; background: #fff; position: relative; top: 50%; border-radius: 5px; display: inline-block; transform: translateY(-50%); } </style> <script> content.onclick = event => { event.stopPropagation(); } onclick = event => { dialog.style.display = 'none'; } btn.onclick = event => { event.stopPropagation(); dialog.style.display = 'block'; } </script>   阻止冒泡显然太凶残的,如果又来一个需求是要给对话框内的点击加监控,而监控框架是基于冒泡实现的,那就会变得很麻烦。想想太极拳中的借力使力,别人一拳头过来未必要强行挡下来,可以试试把对方往施力的方向拽嘛,惯性会让对方「根本停不下来」。所以呢,冒泡我们也不用强行把它停止掉,接着这个冒泡,让它把我们自己需要的信息带到上层元素的事件中,让后根据这些信息来做正确的事情即可。比如下面这个实现就不用冒泡(虽然代码还是很烂,可以别吐槽么?)
<div id="dialog"><span id="content">HEHE</span></div><button id="btn">Open Dialog</button> <style> #dialog { position: fixed; background: rgba(0,0,0,.8); top: 0; left: 0; height: 100%; width: 100%; text-align: center; display: none; } #content { font-size: 64px; padding: 16px 32px; border: 1px solid #ccc; background: #fff; position: relative; top: 50%; border-radius: 5px; display: inline-block; transform: translateY(-50%); } </style> <script> content.onclick = event => { event.dontCloseDialog = 1; } onclick = event => { if (event.dontCloseDialog === 1) return; dialog.style.display = 'none'; } btn.onclick = event => { event.dontCloseDialog = 1; dialog.style.display = 'block'; } </script>   其实这个场景不用冒泡也可以用 contains 轻易实现。这里想告诉大家的只有一件事,整个事件过程中的 event 对象是同一个,可以用来传递信息。
网名:
3.80.32.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^