了解事件
了解事件:
由代码方式和页面内容约定好的一个行为
当 用户操作的时候, 就会触发对应的函数
事件三要素:
1事件源:和谁约定事件(并不一定由事件源触发事件)
2事件类型:约定了一个事件
3事件处理函数:当行为发生时,需要执行的函数
事件绑定:
1 DOM 0级事件
语法:事件源.on事件类型=事件处理函数
特点:只能给同一个事件源同一事件类型绑定一个事件处理函数
2 DOM 2级事件:事件监听
标准浏览器:
语法:事件源.addEventListener('事件类型',事件处理函数)
特点:可以给同一个事件源同一个事件类型绑定多个事件处理函数,
当有多个事件处理函数的时候, 顺序绑定顺序执行
事件类型位置没有 on
IE低版本:
语法:事件源.attachEvent('on事件类型',事件处理函数)
特点:
1. 可以给同一个事件源同一个事件类型绑定多个事件处理函数
2. 当有多个事件处理函数的时候, 顺序绑定倒序执行
3. 事件类型位置需要书写 on
事件解绑
1 DOM 0级 事件解绑
事件源.on事件类型=null
等号赋值为null覆盖原来的事件处理函数,相当于解绑
2 DOM 2级 事件解绑
标准浏览器:
事件源.removeEventListener('事件类型',事件处理函数)
IE低版本:
事件源.detachEvent('on事件类型',事件处理函数)
function handlerA() { console.log('111111111111') }
元素.addEventListener('click', handlerA)
元素.onclick = function () {box.removeEventListener('click', handlerA)}
事件类型
鼠标事件:
click:鼠标左键单击
dblclick:鼠标左键双击
contextmenu:鼠标右键单机
mousedown:鼠标按下(左右键按下都会触发)
mouseup:鼠标抬起
mousemove:鼠标移动(只要鼠标移动就触发)
mouseover:鼠标移入
mouseout: 鼠标移出
mouseenter:鼠标移入
mouseleave:鼠标移出
over 和 out 一套, 当你移入后代元素的时候, 一样会触发
enter 和 leave 一套, 当你移入后代元素的时候, 不会触发
键盘事件
任何元素都能绑定,但不是所有元素都能触发
触发键盘事件,不会考虑中文输入法
一般window,document,表单元素,
keydown 键盘按下事件,任何键盘按键都会触发
keyup 键盘抬起
keypress 键盘键入事件,必须按下真实键入内容的按键 或者回车才会触发
表单事件
绑定给表单元素的事件 form input textarea select
focus 聚焦事件
blur 失焦事件
change 改变事件,在失焦的时候判断, 如果和聚焦的时候不一样, 就会触发
input 输入事件,只要你在表单内输入内容或者删除内容都会触发
reset 重置事件 事件需要绑定在form身上,点击 reset 按钮的时候, 会触发 form 的表单重置行为, 此时触发事件
submit 提交事件 事件需要绑定在 form 标签身上,当你点击 submit 按钮的时候, 会触发 form 的表单提交行为, 此时触发事件
触摸事件 一般移动端
touchstart 触摸开始,当手指触到屏幕的瞬间
touchmove 触摸移动,当手指在屏幕上移动时
touchend 触摸结束,当手指离开屏幕的瞬间
其他事件
selectstart 当需要开始选中文的时候触发
transitionend 过度结束的时候触发,过度多少个属性就触发多少回
。。。。。。
事件对象 event
事件对象:一个对象数据类型,记录了本次事件的所有信息
获取事件对象:
标准事件对象:直接在事件处理函数位置书写一个形参,在事件触发时由浏览器自动传递实参,传递的实参就是事件对象
IE低版本 window.event
var e=e||window.event
事件对象信息-鼠标事件
1 clientX 和 clientY
光标相对于浏览器可是窗口左上角的坐标位置
2 pageX 和 pageY
光标相对于文档流左上角的位置
3 offsetX 和 offsetY
光标相对于 触发事件的元素 左上角的坐标位置
事件对象信息-键盘事件 keyCode
键盘事件就是按下的哪一个键,是否是组合按键
键盘按下事件onkeydown
e = e || window.event
兼容:火狐浏览器FireFox<20的版本用 e.which
2 组合按键:
shiftkey ctrlkey altkey metakey(win command)
返回布尔值:true表示按下,false表示没按下
事件传播
基本概念
事件传播不是在传播事件,是在传播行为,传播路径一定是结构父子级的顺序
传播的过程: 假设你点击在了 inner 元素身上
+ 浏览器窗口(window) 知道你点击事件触发了
+ document 知道你点击事件触发了
+ html 知道你点击事件触发了
+ body 知道你点击事件触发了
+ outer 知道你点击事件触发了
+ center 知道你点击事件触发了
+ inner 知道你点击事件触发了
+ center 知道点击事件触发了
+ outer 知道点击事件触发了
+ body 知道点击事件触发了
+ html 知道你点击事件触发了
+ document 知道你点击事件触发了
+ 浏览器窗口(window) 知道你点击事件触发了
浏览器对于事件处理的机制
+ 所有浏览器都会只在一个传播阶段触发事件
=> 要么把事件触发在 从外向里 的阶段
=> 要么把事件触发在 从里向外 的阶段
+ IE 低版本浏览器
=> 只能在 从里向外 的阶段触发事件
+ 标准浏览器
=> 默认在 从里向外 的阶段触发事件
事件的传播过程:捕获,目标,冒泡
事件的传播 的注意点
+ 问题1: 如果在传播过程中, 某一个环节没有事件绑定, 还会不会继续传播了 ?
=> 会
=> 因为传播的是你点击的这个行为, 不是事件
=> body 上没有点击事件, 只是在 body 上触发点击行为的时候, 没有对应的处理函数
=> 但是点击行为会继续传播到 html 身上
+ 问题2: 如果我给某一个环节绑定一个其他的事件, 会不会触发 ?
=> 不会
=> 因为你传播的是当前的行为, 你点击, 只是传播点击行为
=> document 身上的 contextmenu 需要右键单击行为
+ 问题3: 如果我把 inner 通过定位的方式移出 outer 范围, 还会不会触发了 ?
=> 会
=> 因为事件的传播是按照 结构父子级 的顺序传播
+ 问题4: 把一个 other 元素定位在 inner 内部的时候, 会不会传播到 inner 身上 ?
=> 不会
=> 因为事件的传播是按照 结构父子级 的顺序传播
=> 虽然你定位在了 inner 身上, 但是你的结构父级中没有 inner
=> 就不会传播到 inner 身上
事件冒泡和捕获
1 事件目标
因为事件传播,一个事件不一定由事件源触发,当事件触发的时候,准确触发事件的元素就是事件目标
获取事件目标:var target=e.target || e.srcElement
2 事件捕获,从window到事件目标的过程
3 事件冒泡,从事件目标到window的过程
一个事件:捕获--目标--冒泡
触发事件的时机:
IE低版本只能在冒泡阶段触发事件
标准浏览器:默认在冒泡阶段触发
DOM0级事件不能修改触发阶段
DOM2级事件可以修改触发时机
addEventListener() 第三个参数,默认false冒泡,true捕获
阻止事件传播
就是事件行为到该事件源为止,不再向上传播
语法:
标准浏览器:事件对象.stopPropagation()
IE低版本:事件对象.cancelBubble=true
兼容:try { e.stopPropagation() } catch(err) { e.cancelBubble=true }
默认行为
不需要绑定事件,不需要和事件源约定,当触发行为的时候,就会出现效果的事情
例:a标签,点击跳转,form自动提交
阻止默认行为:
标准浏览器:事件对象.preventDefault()
IE浏览器:事件对象.returnValue=false
兼容:
try { 事件对象.preventDefault } catch(err) { 事件对象.returnValue=false }
事件委托
就是利用事件冒泡,把自己的事件委托给 结构父级 中的某一个
在结构父级的事件内,利用是事件目标去判断准确点击的元素
事件委托的原则上越近越好
优点:对动态渲染的元素比较友好,当元素过多时,减少对DOM的频繁操作