类似于 JQuery 的这样 js 库已经实现了很好的数据绑定机制的封装效果,但只知其然,不知其所以然还有会有种蒙在鼓里的感觉,亲自去分析一下具体的实现,会有一种豁然开朗的感觉
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
一、传统事件模型
传统事件模型中存在局限性。
内联模型以 html 标签属性的形式使用,与 HTML 混写,这种方式无疑造成了修改以及扩展的问题,已经很少使用了。
脚本模型是将事件处理函数写到 js 文件中,从页面获取元素进行对应事件函数的绑定以触发执行。但也存在不足之处:
1. 一个事件绑定多个事件监听函数,后者将覆盖前者。
2. 需要限制重复绑定的情况
3. 标准化 event 对象
二、现代事件绑定
DOM2 级事件定义了两个方法用于添加、删除事件:addEventListener()、removeEventListener(). 他们分别接收三个参数:事件名、函数、冒泡或捕获的布尔值(true 表示捕获,false 表示冒泡)。
与之对应,IE 提供了类似的两个方法 attachEvent() 和 detachEvent(),但 IE 的两个方法存在另外的问题:无法传递 this 对象(IE 中的 this 指向 window)可以使用 call 方法进行对象冒充:
- function addEvent(obj, type, fn) {
- if (typeof obj.addEventListener != 'undefined') {
- obj.addEventListener(type, fn, false);
- } else if (obj.attachEvent != 'undefined') {
- obj.attachEvent('on' + type,
- function() {
- fn.call(obj, window.event);
- });
- }
- };
但由于添加时执行的是匿名函数,因此添加后无法进行删除;另外 IE 提供方法还会有无法顺序执行绑定事件、存在内存泄漏的问题。
为了解决这一系列的问题,就有必要对方法进行进一步的封装,对其他浏览器使用 DOM2 级标准进行,对于 IE,采用基于传统模式的添加、删除,思路为:
1. 添加是使用 JS 的散列表存储对象事件,为每一个对象事件分配一个 ID 值,按添加的调用顺序,先判断是否存在相同的处理函数,不存在的话就依次将事件绑定函数添加到散列表中,这样解决了无法顺序执行以及重复添加的问题
2. 删除时进行遍历函数匹配的判断,存在则删除
总结:
之前对 JS 的事件绑定并没有太深的认识,甚至停留在传统事件绑定模型上,对程序实现上还是认识太浅,这次学习封装库这部分内容时,才学习到很多 JS 上面向对象的应用。虽说类似于 JQuery 的这样 js 库已经实现了很好的数据绑定机制的封装效果,但只知其然,不知其所以然还有会有种蒙在鼓里的感觉,亲自去分析一下具体的实现,会有一种豁然开朗的感觉,也体会到,做好一个兼容性、通用性强的程序更要考虑很多内容,解决很多问题,也正在在这些问题中逐渐清楚很多的。
来源: