JS 与 html 通过事件交互. 事件, 就是文档或浏览器窗口发生的一些特定的交互瞬间. 可以使用侦听器 (或处理程序) 来预订事件, 以便事件发生时执行相应的代码. 这种在传统工程中被称为观察员模式的模型, 支持页面的行为 (JS) 与页面的外观 (HTML 和 CSS) 之前的松散耦合.
13.1 事件流
事件流描述的是从页面中接受事件的顺序.
IE 事件流是事件冒泡流, 而网景事件流是事件流捕获流.
13.1.1 事件冒泡
即事件开始时由最具体的元素 (文档中嵌套层次最深的那个节点) 接收, 然后逐级向上传播到较为不具体的节点(文档).
div->body->HTML->document
IE9,Firefox,Chrome 和 Safari 则讲事件一直冒泡到 Windows 对象.
13.1.2 事件捕获
事件捕获的思想是从不太具体的节点更早接收时间, 而最具体节点应该最后接收到事件. 用意在于事件到达预订目标之前捕获它.
documengt->HTML->body->div
13.1.3DOM 事件流
DOM2 级事件规定的事件流包括三个阶段: 事件捕获阶段, 处于目标阶段和事件冒泡阶段.
13.2 事件处理程序
事件就是用户或浏览器自身执行的某种的动作. 而响应某个事件的函数为事件处理程序或事件侦听器. 事件处理程序的名字以 on 开头, 如 onclick/onload/onmouseover...
13.2.1HTML 事件处理程序
<input type="button" value="Click me" onclick="alert('Clicked')">
事件处理程序使用一些 JS 代码作为值来定义, 因此不能在其中使用未经转义的 HTML 语法字符, 列如 &,"",<,>. 如果要使用双引号则"
- <input type="button" value="Click me" onclick="showMessage()">
- function showMessage(){}
这样指定事件处理程序会创建一个封装着元素属性值的函数, 这个函数有一个局部变量 event, 也就是事件对象
<input type="button" value="Click me" onclick="alert(event.type)">
在这个函数内部, this 值等于事件的目标元素.
<input type="button" value="Click me" onclick="alert(this.value)">
关于这个动态创建的函数, 它扩展了作用域.
- function(){
- with(document){
- with(this){
- // 元素的属性值
- }
- }
- }
- <input type="button" value="Click me" onclick="alert(value)">
13.2.2DOM0 级事件处理程序
- // this 引用当前元素
- let btn = document.getElementById('myBtn')
- btn.onclick = function(){
- alert(this.id)
- }
- // 删除事件处理程序
- btn.onclick = null
13.2.3DOM2 级事件处理程序
addEventListener(),removeEventListener()
三个参数: 要处理的事件名, 作为事件处理程序的函数和一个布尔值(true 为捕获阶段调用, false 为冒泡阶段调用)
btn.addEventListener('click',function(){},false)
通过 addEventListener()添加的事件处理程序只能使用 removeEventListener()来移除, 移除时传入的参数与添加处理程序时使用的参数相同. 意味添加的匿名函数无法移除.
- let handler = function(){
- }
- btn.addEventListener('click',handler,false)
- btn.removeEventListener('click',handler,false)
13.2.4IE 事件处理程序
- btn.attachEvent("onclick",function(){
- })
- btn.deleteEvent("onclick",function(){
- })
注意是 onclick 不是 click
13.2.5 跨浏览器事件处理程序
13.3 事件对象
在触发 DOM 上的某个事件时, 会产生一个事件对象 event, 这个对象中包含着所有与事件有关的信息. 包括导致事件的元素, 事件的类型以及其他与特定事件相关的信息. 列如, 鼠标操作导致的事件对象中会包含鼠标位置的信息, 而键盘操作导致的事件对象中会包含与按下的键有关的消息.
13.3.1DOM 中的事件对象
- btn.onclick = function(event){
- alert(event.type) // 'click'
- }
event 对象包含与创建它的特定事件有关的属性和方法.
在事件处理程序内部, 对象 this===currentTarget, 而 target 则只包含事件的实际目标.
如果事件处理程序在目标元素上, 则 this,cuttentTarget 和 target 相同.
- btn.onclick=function(event){
- // event.currentTarget=event.target=this
- }
- body.onclick=function(event){
- // event.currentTarget=this=document.body
- // event.target=document.getElementById('myBtn')
- }
preventDefault()方法
阻止特定事件的默认行为. cancelable 属性为 true 才可以用 preventDefault()来取消起默认行为.
stopPropagation()
立即停止事件在 DOM 层次中的传播
eventPhase 属性
用来确定事件当前处于事件流的哪个阶段
1 为捕获
2 为处于目标对象上
3 为冒泡
- btn.onclick=function(event){
- alert(event.eventPhase) // 2
- }
- document.body.addEventListener('click',function(){
- alert(event.eventPhase) // 1
- },true)
- document.body.onclick=function(event){
- alert(event.eventPhase) // 3
- }
13.3.2IE 中的事件对象
DOM0 级添加的事件 event 对象作为 Windows 对象的一个属性存在
- btn.onclick=function(event){
- // event==Windows.event
- }
13.3.3 跨浏览器的事件对象
13.4 事件类型
13.4.1UI 事件
UI 事件指的是那些不一定与用户操作有关的事件.
1. load 事件
当页面完全加载后(包括所有图像, JS 文件, CSS 文件等外部资源), 就会触发 Windows 上面的 load 事件. 有两种定义 onload 事件的方式
JS 形式
EventUtil.addHandler(Windows,'load',function(event){alert('Loaded!')})
HTML 形式
- <body onload="alert('Loaded!')">
- </body>
- <img>
- 上可以加 onload
2.unload 事件
在文档被完全卸载后触发. 只要用户从一个页面切换到另一个页面, 就会发生 unload 事件. 利用该事件可以清除引用, 避免内存泄漏.
既然 unload 事件是在一切都被卸载之后才触发, 那么在页面加载后存在的那些对象, 此时就不一定存在了, 此时, 操作 DOM 节点或者元素的样式都会导致错误.
3. resize 事件
当浏览器窗口被调整到一个新的高度或宽度时, 就会触发 resize 事件. 这个事件在 Windows 上触发, 因此可以通过 JS 或者 body 元素中的 onresize 特性来指定事件处理程序.
IE,Safari,Chrome,Opera 窗口变化了 1 像素就触发
4. scroll 事件
在混杂模式下, 可以通过 body 元素的 scrollLeft 和在 srollTop 来监控这一变化.
在标准模式下, 除 Safari(根据 body)所有其他浏览器都通过 < HTML > 元素来反映这一变化.
在文档被滚动期间重复触发.
13.4.2 焦点事件
焦点事件会在页面元素获得或失去焦点是触发. 利用这些事件并与 document.hasFocus()方法及 document.activeElement 属性配合, 可以知晓用户在页面上的行踪.
blur
在元素失去焦点时触发. 这个事件不会冒泡, 所有浏览器都支持.
focus
在元素获得焦点触发. 这个事件不会冒泡, 所有浏览器都支持.
focusin
在元素获得焦点时触发, 冒泡. IE,Safari,Opera,Chrome
focusout
在元素失去焦点时触发, 冒泡. IE,Safari,Opera,Chrome
13.4.3 鼠标滚轮事件
click
单击主鼠标按钮或者按下回车键时触发
dblclick
双击主鼠标按钮时触发
mousedown
按下任意鼠标按钮时触发, 不能通过键盘触发这个事件
mouseup
在用户释放鼠标按钮时触发. 不能通过键盘触发这个事件
mouseenter
在鼠标光标从元素外部首次移动到元素范围之内时触发. 不冒泡, 而且在光标移动到后代元素上不触发.
mouseleave
在位于元素上方的鼠标移动到元素范围之外时触发, 不冒泡, 而且在光标移动到后代元素上不触发.
mousemove
当鼠标指针在元素内部移动时重复触发, 不能通过键盘触发.
mouseout
在鼠标指针位于一个元素上方, 然后用户将其移入另一个元素时触发. 不能通过键盘触发
mouseover
在鼠标指针位于一个元素外部, 然后用户将其首次移入另一个元素边界之内触发. 不能通过键盘触发.
除了 mouseenter 和 mouseup 其他都冒泡, 也可以取消, 但是取消鼠标事件将会影响浏览器的默认行为.
只有在同一个元素上触发 mousedow 和 mouseup 事件, 才会触发 click 事件, 若其中一个被取消, 就不会出发 click 事件. dblclick 类似.
触发顺序如下
- Mousedown
- Mouseup
- Click
- Mousedown
- Mouseup
- Click
- Dblclick
可以用一下代码检验浏览器是否支持上面的事件
- Let isSupported = document.implementation.hasFeature('MouseEvents','2.0')
- Let isSupported = document.implementation.hasFeature('MouseEvent','3.0')
来源: http://www.bubuko.com/infodetail-3344926.html