注册事件
传统注册事件:on-开头, 如onclick
监听注册事件: addEventListener()
//传统方法 btn.onclick = function() { console.log('传统方法') } //监听注册事件 IE9+ btn.addEventListener('click', function(){ console.log('监听注册方法') }) //IE9- btn.attachEvent('onclick', function(){ console.log('IE9-版本支持') })
完整形式:eventTarget.addEventListener(type, listener [,useCapture])
type: 事件类型字符串 比如 click mouseover 注意不带on
listener: 事件处理函数 事件发生时 会调用该监听函数
useCapture: 可选参数 是一个布尔值 默认是false
删除事件
传统删除事件:设置为null
监听删除事件:removeEventListener()
//传统方式 (点击一次后解绑 再点不会输出) div.onclick = function(){ console.log('传统方法') div.onclick = null } //监听删除事件 IE9+ div.addEventListener('click', fn) function fn() { console.log('监听删除方法') div.removeEventListener('click', fn) }
注意: 事件类型为字符串并且不加on
DOM 事件流
三阶段
JS代码中只能执行 事件捕获 或者 事件冒泡 中的一个阶段
onclick 和 attachEvent()(IE9-支持) 只能得到 事件冒泡 阶段
当 addEventListener() 第三个参数是 true 那么则处于 事件捕获 阶段, false 处于 事件冒泡 阶段
事件捕获和事件冒泡的 css & html 代码块
//css代码块 .father{ width: 200px; height: 200px; background-color: aquamarine; } .son{ width: 100px; height: 100px; background-color: lightblue; } //html代码块 <div class='father'> <div class='son'>son盒子</div> </div>
事件捕获
//事件捕获 (addEventListener 第三个参数是 true) //document -> html -> body -> father -> son var son = document.querySelector('.son') son.addEventListener('click', function() { alert('son') },true) var father = document.querySelector('.father') father.addEventListener('click', function() { alert('father') },true) //点击 son 的 div 会先弹出 father 再弹出 son
事件冒泡
//事件冒泡 (addEventListener 第三个参数是 false) //son -> father -> body -> html -> document var son = document.querySelector('.son') son.addEventListener('click', function() { alert('son') },false) var father = document.querySelector('.father') father.addEventListener('click', function() { alert('father') },false) document.addEventListener('click', function(){ alert('document') }) //点击 son 的 div 会依次弹出 son father document
注意:在实际开发中, 我们更关注事件冒泡.有些事件没有冒泡, 如:onblur onfocus onmouseenter onmouseleave等
事件对象 event
- event 就是一个事件对象 写到我们 监听函数 的 小括号里, 当 形参 来看
- 事件对象只有有了事件才会存在 它是 系统 给我们 自动创建 的,不需要 我们 传递参数
- 事件对象 是 我们事件的一系列
相关数据的集合
, 跟事件相关的, 比如鼠标点击就包含了鼠标的相关信息 - 这个事件对象我们可以自己命名, 比如
event
、e
- 事件对象也有
兼容性问题
, IE678 通过window.event
//css代码 div{ width: 100px; height: 100px; background-color: lightblue; } //html代码 <div>123</div> //js代码 var div = document.querySelector('div') div.addEventListener('click', function(e){ console.log(e); console.log(window.event); e = e || window.event //兼容处理 }) //输出一个[[Prototype]]: PointerEvent 类型的事件
常见事件对象属性和方法
1.e.target 返回的是触发事件的对象 (元素)
2.this 返回的是绑定事件的对象 (元素)
区别
e.target: 点击了哪个元素, 就返回哪个元素
this: 哪个元素绑定了这个点击事件, 就返回哪个元素
//css代码 div{ width: 100px; height: 100px; background-color: lightblue; } //html代码 <div>123</div> <ul> <li>abc</li> <li>abc</li> <li>abc</li> </ul> //js代码 var div = document.querySelector('div') div.addEventListener('click', function(e){ console.log(e.target); //输出<div>123</div> console.log(this); //输出<div>123</div> }) var ul = document.querySelector('ul') ul.addEventListener('click', function(e){ // 给 ul 绑定了事件 那么this就指向ul console.log(this); //输出 <ul>...</ul> // e.target 指向我们点击的那个对象 点击的是li, e.target 指向的就是li console.log(e.target); //<li>abc</li> })
- 返回事件类型 e.type
//html代码 <div>123</div> //js代码 var div = document.querySelector('div') div.addEventListener('click', fn) function fn(e){ console.log(e.type); //点击 div 输出事件类型 click }
- 阻止默认行为 e.preventDefault()
(让链接不跳转 或 让提交按钮不提交)
//html代码 <a href="http://www.baidu.com">百度</a> //js代码 var a = document.querySelector('a') a.addEventListener('click', function(e){ e.preventDefault() //DOM 标准写法 点击链接不跳转 })
阻止事件冒泡
1.标准方法: e.stopPropagation()
2.非标准方法: e.cancelBubble = true
//css代码 .father{ width: 200px; height: 200px; background-color: aquamarine; } .son{ width: 100px; height: 100px; background-color: lightblue; } //html代码 <div class='father'> <div class='son'>son盒子</div> </div> //js代码 var son = document.querySelector('.son') son.addEventListener('click', function(e) { alert('son') e.stopPropagation() //stop 停止 Propagation传播 e.cancelBubble = true //非标准 cancel 取消 Bubble 泡泡 },false) var father = document.querySelector('.father') father.addEventListener('click', function() { alert('father') },false) document.addEventListener('click', function(){ alert('document') }) //点击 son 的 div 时, 因为阻止了事件冒泡, 所以只会弹出 son 不会冒泡到 father 和 document
事件委托
事件委托:不是每个子节点单独设置事件监听器,而是事件监听器设置在其 父节点 上,然后利用 冒泡原理 影响设置每个子节点
核心原理:给父节点添加监听器 利用事件冒泡影响每一个子节点
作用: 只操作一次DOM, 提高了程序的性能
//html代码 <ul> <li>八岁</li> <li>八岁</li> </ul> //js代码 var ul = document.querySelector('ul') ul.addEventListener('click', function(e){ //e.target得到点击的对象 e.target.style.backgroundColor = 'lightblue' }) //获取到ul, 给其添加监听器, 若点击小li, 该行背景颜色设置为淡蓝色. 若点击ul, 所有行设置为淡蓝色
不积跬步无以至千里 不积小流无以成江海