测试DOM0级事件和DOM2级事件的堆叠
1. 问题
如果大家看过北风网CJ讲师的Javascript视频教程,就可以看到其封装了一个很强的事件添加和删除函数,如下所示
function addEvent(obj, evtype, fn) {
//符合W3C的事件模型
if (obj.addEventListener) {
obj.addEventListener(evtype,fn,false);
return obj;
}
//IE或Opera浏览器
if (!obj.functions) obj.functions={};
if (!obj.functions[evtype])
obj.functions[evtype] = [];
var functions=obj.functions[evtype];
for (var i=0;i<functions.length;i++) {
if (functions[i] === fn) return obj;
}
functions.push(fn);
if (typeof obj["on"+evtype]=="function") {
if (obj["on"+evtype]!=handler)
functions.push(obj["on"+evtype]);
}
obj["on"+evtype]=handler;
return obj;
}
function delEvent(obj,evtype,fn) {
if (obj.removeEventListener) {
obj.removeEventListener(evtype,fn,false);
return obj;
}
var fns=obj.functions || {};
fns=fns[evtype] || [];
for (var i=0;i<fns.length;i++) {
if (fns[i]==fn) {
fns.splice(i,1);
return obj;
}
}
}
它因为各种原因,没有采用IE的DOM2级事件添加函数attachEvent,以期达到非常完美的兼容性,据说可以到 IE5.5 或以下。分析代码页可以看到,它通过给DOM元素添加一个以 on + ‘type’ 为名的属性,其对应的值是一个处理函数的数组,本质来说就是仅仅利用 DOM0级提供的接口 elem.onclick = function () { ...} 来添加事件。
一直以来没有发现什么问题,直到给别人使用时,发现IE6~8通过该封装函数 addEvent 添加的 load 事件并没有执行,调试代码发现别人在 JS 中通过 window.onload 赋了一个处理函数,顿时明白这种 addEvent 封装的一个大Bug,原因很简单,通过DOM0级提供的事件接口多次添加时,后面的函数会覆盖前面的,而这种 addEvent 本质上就是一个 DOM0级函数,所以肯定会被后面的覆盖。
也就是说, addEvent 是假定网页JS代码中不使用 DOM0级添加事件。
2. 构建测试页面和代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<script src="dom.event.js"></script>
<title>测试DOM0级事件和DOM2级事件的堆叠</title>
</head>
<body>
<textarea name="have" id="output" cols="30" rows="10"></textarea> <button id="testBtn">测试</button> <script type="text/javascript">
var btn = document.getElementById('testBtn');
var output = document.getElementById('output'); // 标准的 DOM2 级事件添加方法
// if (btn.addEventListener) {
// btn.addEventListener('click', function () {
// output.value += 'DOM 2 Level Click\r\n';
// });
// } else {
// btn.attachEvent('onclick', function () {
// output.value += 'DOM 2 Level Click\r\n';
// })
// } // 使用封装的 addEvent 函数
// addEvent(btn, 'click', function () {
// output.value += 'DOM 2 Level Click\r\n';
// }); btn.onclick = function () {
output.value += 'DOM 0 Level Click 111111\r\n';
} btn.onclick = function () {
output.value += 'DOM 0 Level Click 222222\r\n';
} </script>
</body>
</html>
测试1:点击测试按钮,可以看到textarea 中只是输出 DOM 0 Level Click 22222 信息,也就是后面添加的事件覆盖了之前添加的,跟变量赋值是一个道理!!
测试2:将 DOM2 级事件添加的代码反注释掉,打开网页点击测试按钮,可以看到会输出 DOM 2 Level Click 和 DOM 0 Level Click 22222,也就是说DOM0 级事件和 DOM2 级添加的事件都会处理,DOM0级并不会覆盖 DOM2 添加的事件处理函数。
测试3: 将 DOM2 级事件保持注释状态,反注释掉 addEvent 部分, 可以看到只会输出 DOM 0 Level Click 22222。
测试4: 在测试3 的基础上, 注释掉后面两个 DOM0 级添加事件的代码,以测试 addEvent 的输出,可以看到它输出 DOM 2 Level Click, 从而证明测试3中其被覆盖的结论。
3. 总结
1) DOM0 级事件和 DOM2 级事件可以共存;
2) 尽量不要写 DOM0 级事件,特别是代码提供给别人使用时,绝对不能写!
测试DOM0级事件和DOM2级事件的堆叠的更多相关文章
- DOM1级问题与DOM2级事件
前几天有小伙伴问过我一个问题,为什么有DOM 0级事件以及DOM2级事件,但是却没有DOM1级事件呢?那我们今天就来说一说DOM的级别问题. 同时推荐伙伴们可以看看尚学堂有关JavaScript BO ...
- dom0级事件和dom2级事件
dom0级事件 <a href="#" id="hash" onclick="fn();fn1();"> <button ...
- 【20190226】JavaScript-知识点记录:dom0级事件,dom2级事件
DOM0级事件处理程序: 通过将元素的事件处理程序属性(如onclick)的值设置为一个函数来指定事件处理程序的方法称为DOM0级方法,它被认为是元素的方法,这时候的事件处理程序是在元素的作用域中运行 ...
- 关于DOM事件流、DOM0级事件与DOM2级事件
一.DOM 事件模型 DOM 事件模型包括捕获和冒泡,捕获是从上往下到达目标元素,冒泡是从当前元素,也就是目标元素往上到 window 二.流 流的概念,在现今的 JavaScript 中随处可见.比 ...
- js DOM0级事件和DOM2级事件
注册事件有两种方式,分别是DOM0级和DOM2级 DOM0级就是通过事件绑定的形式dom元素只能有(绑定)一个事件处理函数,他的特点是同一个元素绑定相同事件, 后面函数会覆盖前面的 绑定: dom.o ...
- DOM0级事件处理、DOM2级事件处理
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 关于DOM2级事件的事件捕获和事件冒泡
DOM2级事件中addEventListener的执行机制,多个addEventListener同时添加时的执行先后规律: W3C的DOM事件触发分为三个阶段:①.事件捕获阶段,即由最顶层元素(一般是 ...
- JavaScript 之默认行为 DOM2级,事件委托机制
1. 事件默认行为及阻止方式 1.1 浏览器的默认行为 JavaScript事件本身所具有的属性,例如a标签的跳转,Submit按钮的提交,右键菜单,文本框的输入等. 1.2 ...
- javaScript——DOM1级,DOM2级,DOM3级
DOM0,DOM2,DOM3事件处理方式区别:http://www.qdfuns.com/notes/11861/e21736a0b15bceca0dc7f76d77c2fb5a.html JS中do ...
随机推荐
- 调色板QPalette类用法详解(附实例、源码)(很清楚:窗口背景色 前景色 按钮的颜色 按钮文本的颜色 )
http://blog.csdn.net/rl529014/article/details/51589096
- 基于Visual C++2013拆解世界五百强面试题--题11-查找数字出现次数
在排序数组中,找出给定数字出现的次数比如{ 1, 2, 2, 2, 3}中2的出现次数是3次 我们可使用二分查找发,分别查找出2最先出现的位置和最后出现的位置相减即可. 下面是上代码: #includ ...
- 2014第35周三jquery最近用到的内容总结
1.文档加载后执行: $(document).ready(function(){//onload();}); 或$(function(){//onload();}) 2. 选择器使用: $(" ...
- Oracle select into from 和 insert into select
select into from SQLSERVER 创建表: select * into aaa from bbb Oracle 创建表: create table aaa as select * ...
- JAVA GUI学习 - JTabbedPane选项卡组件学习
public class JTabbedPaneKnow extends JFrame { JTabbedPane jTabbedPane; JPanel jPanelRed; JPanel jPan ...
- POJ-1010 Stamps
[题目描述] 题目大意是:邮票发行商会发行不同面值.不同种类的邮票给集邮爱好者,集邮爱好者有总目标面额,通过不同的邮票组合(总数在4张以内)达到该面值,卖给集邮爱好者.另外,发行商发行的邮票面值最多2 ...
- HDU-4866-Shooting(函数式线段树)
Problem Description In the shooting game, the player can choose to stand in the position of [1, X] t ...
- Ext JS学习第十六天 事件机制event(一)
此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件,相信你一定不陌生, 基本事件是什么?就类似于click.keypress.focus. ...
- Software Version --hdu1976
#include using namespace std; int main() { int T; cin>>T; int a1,b1,c1; int a2,b2,c2; while(T- ...
- Servlet学习的两个案例之网站访问次数的统计
一.统计次数的Servlet源码 package com.shanrengo; import java.io.IOException; import javax.servlet.ServletCont ...