历史:
- IE3和Netscape Navigator2 : 作为分担服务器负载的一种手段;
- IE4和Naviscape4 : 提供了相似却不相同的API;
- DOM2规范制定 : 开始尝试标准化DOM事件;
- DOM2实现 : IE9、Firefox、Opera、Safari和Chrome全部实现‘DOM2级事件’核心部分;
+ DOM3级出现 : API变得更加繁琐。
13.1 事件流
13.1.1 事件冒泡 : 最具体的元素->…->document
支持情况: 所有浏览器。
浏览器 | 表现 |
---|---|
IE5.5— | 最具体的元素->…->body->document |
IE9、Firefox、Chrome、Safari | 最具体的元素->…->body->html->document->window |
13.1.2 事件捕获 : document->html->body->…->最具体的元素
说明:DOM2级规范
- 支持情况:IE9、Safari、Chrome、Opera、Firefox
- 不支持情况: 所有老版本浏览器
13.1.3 DOM事件流
支持情况: IE9、Safari、Chrome、Opera、Firefox
- 会创建一个封装着元素属性值的函数
- this : 当前dom
- event : 事件对象
- 扩展了作用域
1 | //形象说明作用域的扩展情况 |
方式一 : 直接在标签中嵌入JS代码
注意:不能使用未经转义的HTML语法字符!
1 | <input type='button' value='Click Me' onclick="alert('Clicked')" /> |
方式二 : 调用其他地方定义的脚本
1 | <script> |
13.2.2 DOM0级事件处理程序 : 将函数赋值给一个事件处理程序属性
说明
- DOM0级方法指定的事件处理程序被认为是元素的方法,因此程序中的this引用当前元素;
- 这种事件处理程序在事件流的冒泡阶段处理;
- 每个元素(包括window和document)都有自己的的事件处理程序。
1 | var btn = document.getElementById('myBtn'); |
13.2.3 DOM2级事件处理程序
兼容性:IE9 Firefox Safari Chrome Opera
####addEventListener()
说明: 添加事件,3个参数,要处理的事件名、作为事件处理处理程序的函数、布尔值(true表示捕获阶段;false表示冒泡阶段)
- 依附元素的作用域
- 可以添加多个事件处理程序,事件触发后按添加的顺序执行
- addEventListener()添加的事件处理程序只能使用removeEventListener()来移除
- 移除时传入的参数与添加处理程序使用相同的参数
- 添加的匿名函数无法移除
####removeEventListener()
说明:移出addEventListener()添加的事件处理程序,参数和 addEventListener() 保持一致
注意: 将事件添加到事件的冒泡阶段而不是捕获阶段可以最大程度兼容各种浏览器,除非需要在事件到达目标之前截获事件。
1 | var btn = document.getElementById('myBtn'); |
13.2.4 IE事件处理程序
注意:该方法没有考虑只支持DOM0级浏览器只支持一个事件处理程序的问题,如果多次绑定处理程序,只有最后一个有效。
####attachEvent()
说明:添加事件,两个参数,事件处理程序名称、事件处理函数
- IE8-只支持事件冒泡,因此会被添加到冒泡阶段
- 事件名带
on
前缀 - 事件处理程序在全局作用域中运行,
this
等于window
- 可以添加多个事件处理程序,事件触发后按与添加的相反的顺序执行
- 移除时传入的参数与添加处理程序使用相同的参数
- 添加的匿名函数无法移除
attachEvent
添加的事件处理程序只能使用detachEvent
移除- ####detachEvent()
说明:移除通过attachEvent()添加的事件处理函数
1 | var btn = document.getElementById('myBtn'); |
13.3 事件对象
说明: 触发DOM上的某个事件是会产生一个事件对象event(DOM0或DOM2),包含所有与时间有关的信息。
特点
- 所有浏览器都支持event对象,但支持方式不同
- 只在事件处理程序执行期间存在,执行完毕后被销毁
不同事件类型可用的属性和方法不同,都包括的成员如下
- event.type : 事件类型
1 | var btn = document.getElementById('myBtn'); |
- event.target: 事件的实际目标(最具体的那个元素)
- event.currentTarget: 和this相同,注册事件的那个元素
- event.eventPhase :事件当前所在的事件流的阶段
- 捕获阶段调用事件处理程序
- 事件处理程序处在目标对象上
- 冒泡阶段调用事件处理程序
1 | var btn = document.getElementById('myBtn'); |
- event.preventDefault() : 取消默认行为
- event.stopPropagation() : 立即停止事件在DOM层次中的传播,即取消进一步的事件捕获或冒泡
13.3.2 IE中的事件对象
说明:访问IE中的event对象的方式取决于指定事件处理程序的方法
####window.event(DOM0级方法)
1 | var btn = document.getElementById('myBtn'); |
####作为参数对象(attachEvent())
1 | var btn = document.getElementById('myBtn'); |
####直接访问event(HTML中)
1 | <input tyep='button' value='Click Me' onclick='alert(event.type)' /> |
13.3.3 跨浏览器的事件对象
说明:创建一个兼容的操作事件对象的工具对象:因为兼容IE不支持阻止事件捕获
1 | var EventUtil = { |
13.4 事件类型
- DOM2级事件
- DOM3级事件(以DOM2为基础)
- UI事件
- 焦点事件
- 鼠标事件
- 滚轮事件
- 文本事件
- 键盘事件
- 合成事件
- 变动事件
变动名称事件
HTML5定义的一组事件
- DOM和BOM中实现的其它专有事件(没有规范)
13.4.1 UI事件
历史:出现在DOM规范之前,被规范保留。
分类:现有的UI事件
事件名称 | DOM | 触发时机 | 备注 |
DOMActive | 任何元素 | 元素已经被用户操作激活 | 被DOM3废弃 |
load | window | 页面加载完后 | HTML事件 |
框架集 | 所有框架都加载完毕 | ||
<img> | 图像加载完毕 | ||
<object> | 嵌入的内容加载完毕 | ||
unload | window | 页面完全卸载 | HTML事件 |
<img> | 无法加载图片 | ||
框架集 | 所有框架都卸载 | ||
<object> | 嵌入的内容卸载完毕 | ||
abort | <object> | 用户停止下载,嵌入的内容没有加载完 | HTML事件 |
error | window | JavaScript错误 | HTML事件 |
<img> | 无法加载图像 | ||
<object> | 无法加载嵌入内容 | ||
框架集 | 有框架无法加载 | ||
select | <input> | 用户选择文本框一个或多个字符 | HTML事件 |
<textarea> | 用户选择文本框一个或多个字符 | ||
resize | window或框架 | 窗口或框架变化 | HTML事件 |
scroll | 带滚动条的元素 | 用户滚动带滚动条的元素中的内容 | HTML事件<body>元素中包含加载元素的滚动条 |
####为UI事件定义事件处理程序
#### 13.4.1.1 load事件
案例一:以body为例
方式一: JS(推荐)
+ 使用了跨浏览器的脚本;
+ 传入的event不包含有关这个时间的任何附加信息;
+ 兼容DOM时,event.target会被设置为document;IE不会为其设置srcElement属性;
+ “DOM2级事件”规范应该在document上而不是window上触发load事件,但所有浏览器都在window上面实现了该事件(确保向后兼容)。
1 | EventUtil.addHandler(window, 'load', function(event){ |
方式二: 为元素添加onload属性
1 |
|
案例二:img
方式一
1 | var image = document.getElementById('myImage'); |
方式二
1 | <img src='smile.gif' onload='alert('Image loaded.')'> |
案例三:创建新的
<img>
元素,同时指定一个事件处理程序+ 要在window上的onload事件触发后才添加DOM中,否则document.body会报错;
+ 一旦设置了src属性,新创建的图像就开始加载图像,和是否添加到文档中无关;
方式一: DOM的方式
注意:[IE8-]没有添加到DOM中的节点触发load事件时不会生成event对象。
1 | EventUtil.addHandler(window, 'load', function(event){ |
方式二: Image对象
+ 可以像使用
<img>
元素一样使用Image对象(并非所有浏览器都将Image对象实现为<img>
);+ 无法添加到DOM中;
+ 【IE8- 】Image对象触发load事件不会生成event对象。
1 | EventUtil.addHandler(window, 'load', function(){ |
案例四: script元素
说明:指定src属性并将元素添加到文档后才开始下载。
兼容性问题
|浏览器版本|script元素onload事件|event.target|
|—|—|—|
|大多数浏览器|支持|