什么是事件代理(Event Delegation)?
如果不太了解的朋友,可详细阅读:《Event delegation in JavaScript》,这里不再累述。
首先让我们一起来回顾一些常识:
通常支持事件冒泡(Event Bubbling)的事件类型为鼠标事件和键盘事件,例如:mouseover, mouseout, click, keydown, keypress。
接口事件则通常不支持事件冒泡(Event Bubbling),例如:load, change, submit, focus, blur。
很明显:focus 和 blur 都属于不支持冒泡的接口事件。既然都不支持冒泡,那又如何实现事件代理呢?
可以换个角度,逆向思维,尝试事件捕获(Event Capturing,除了IE,现在流行的标准浏览器均支持)。
测试后会发现,如果你捕获 focus 或 blur 事件,目标元素的祖先元素均执行事件函数。至于为什么?或许是实现的一个 BUG。
el.addEventListener('focus', focusHandler, true);
el.addEventListener('blur', blurHandler, true);
那对于 IE ,我们如何实现呢?
非常幸运,IE 下支持 focusin 和 focusout 事件,非常类似于 focus 和 blur 事件,唯一不同的是,这两种事件支持事件冒泡(Event Bubbling)。
el.onfocusin = focusHandler;
el.onfocusout = blurHandler;
很完美的解决方案:
if (document.addEventListener) {
el.addEventListener('focus', focusHandler, true);
el.addEventListener('blur', blurHandler, true);
} else {
el.onfocusin = focusHandler;
el.onfocusout = blurHandler;
}
当你下次看到 YUI 2.8 的 event/event-debug.js 源码中下面几段代码时,一定会清晰很多:
// String constants used by the addFocusListener and removeFocusListener methods
FOCUSIN = "focusin",
FOCUSOUT = "focusout";
....
_specialTypes: {
focusin: (isIE ? "focusin" : "focus"),
focusout: (isIE ? "focusout" : "blur")
},
....
addListener: function (el, sType, fn, obj, overrideContext) {
var capture = ((sType == FOCUSIN || sType == FOCUSOUT) && !YAHOO.env.ua.ie) ? true : false;
return this._addListener(el, this._getType(sType), fn, obj, overrideContext, capture);
}
推荐阅读
- 操作系统|[译]从内部了解现代浏览器(1)
- web网页模板|如此优秀的JS轮播图,写完老师都沉默了
- JavaScript|vue 基于axios封装request接口请求——request.js文件
- vue.js|vue中使用axios封装成request使用
- JavaScript|JavaScript: BOM对象 和 DOM 对象的增删改查
- JavaScript|JavaScript — 初识数组、数组字面量和方法、forEach、数组的遍历
- JavaScript|JavaScript — call()和apply()、Date对象、Math、包装类、字符串的方法
- JavaScript|JavaScript之DOM增删改查(重点)
- javascript|vue使用js-xlsx导出excel,可修改格子样式,例如背景颜色、字体大小、列宽等
- javascript|javascript中的数据类型转换