Web 技术研究所

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

事件引导 - 非冒泡事件监控

  对于可冒泡的事件,我们只要在文档的根上检测它的冒泡即可对其监控。但很多事件确实是用户操作产生,却又是非冒泡的。比如 focus 事件,这类事件就无法直接在全局监控。还有很多事件的冒泡存在浏览器差异,要兼容到 IE8 还真有点困难。

一些基本方案

  focus 这种事件虽然不会冒泡,但是正向的传递依然是会产生的,如果不考虑 IE8 兼容的话可以考虑在正向传递中拦截这个事件,比如这么做 <input />
<script>
document.addEventListener('focus', function(e) {
  console.log(e.target);
}, true); <!-- 注意最后一个参数是 true
</script>
  这个方案在 IE8 上就不行了,因为 IE8 不支持正向事件捕获。
  也许有人会想遍历文档对所有控件添加这个事件?如果文档是静态的话这么做是可行的,但很多时候文档内的 DOM 是动态加载的,甚至像单页应用级的东西,整个 DOM 都是动态生成的。如果一直扫描文档去添加事件,性能上就会有问题。

解决方案与坑

  我的解决方案是使用可冒泡的事件去引导。有些可冒泡事件是很快的,比如 mousedown、keydown。全局监控这些事件,当这些事件触发的时候给目标元素添加 focus 之类的非冒泡事件。这样 focus 也就能被监控了。
  但是有些情况下,点击的目标元素并非直接是控件。比如这样的结构 <label>
  <span>点我就好,不用直接点控件</span> <input/>
</label>
  这时候我们监控到的 mousedown 并不会直接在 INTPU 上触发。

填坑,用更复杂的逻辑

  像 LABEL 这样的东西存在就会影响 INPUT 的点击响应范围。于是当点击的时候我们就需要向父节点追溯,看看有没有存在 LABEL 或类似的东西。如果找不到的话,点击事件就这么不了了之了。要是找到了,那么就得从这个找到的元素上遍历后代元素,给它后代元素的控件添加 focus 事件。

悲伤的叹息

  绕了这么一大圈,结果只为解决这么小的问题,IE8 何时才能死呢?

网名:
34.203.213.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^