事件对象
• 什么是事件对象?
• 就是当你触发了一个事件以后, 对该事件的一些描述信息
• 例如:
° 你触发一个点击事件的时候, 你点在哪个位置了, 坐标是多少
° 你触发一个键盘事件的时候, 你按的是哪个按钮
• 每一个事件都会有一个对应的对象来描述这些信息, 我们就把这个对象叫做 事件对象
• 浏览器给了我们一个 黑盒子, 叫做 Windows.event , 就是对事件信息的所有描述
• 这个玩意很好用, 但是一般来说, 好用的东西就会有 兼容性问题 , 在 IE 低版本里面这个东西好用, 但是在 高版本 IE 和 Chrome 里面不好使了
• 我们就得用另一种方式来获取 事件对象, 在每一个事件处理函数的行参位置, 默认第一个就是 事件对象
- var box = document.querySelector('.box')
- console.log(box)
- box.onclick = function fn1(e){
- //Windows.event.X 轴坐标点信息 根据页面来显示的
- console.log(e.x)
- }
• 综上所述, 我们以后在每一个事件里面, 想获取事件对象的时候, 都用兼容写法
box.onclick = function (e) { // 兼容写法 e = e || Windows.event }
offsetX 和 offsetY
• 是相对于你点击的元素的边框内侧开始计算 有边框的话会出现负值
var box = document.querySelector('.box') box.onclick = function (e) { // 兼容写法 console.log(e.offsetX) }
clientX 和 clientY
• 是相对于浏览器窗口来计算的, 从浏览器可视区域左上角开始, 即是以浏览器滑动条此刻的滑动到的位置为参考点, 随滑动条移动 而变化
var box = document.querySelector('.box') box.onclick = function (e) { // 根据你浏览器的窗口来计算的, Y 轴不包含导航地址栏和标签栏这些 console.log(e.clientY) }
• 不多说上图 此时 Y 轴的值会随着我滚动而发生改变
pageX 和 pageY
• 是相对于整个页面的坐标点, 不管有没有滚动, 都是相对于页面拿到的坐标点 从页面左上角开始, 即是以页面为参考点, 不随滑动条移动而变化
var box = document.querySelector('.box') box.onclick = function (e) { // 根据你浏览器的窗口来计算的, Y 轴不包含导航地址栏和标签栏这些 console.log(e.pageY) console.log(e.pageX) }
上图
常见的事件
• 大致分为几类, 浏览器事件 / 鼠标事件 / 键盘事件 / 表单事件 / 触摸事件
事件监听
• addEventListener : 非 IE 7 8 下使用
• 语法: 元素. addEventListener('事件类型', 事件处理函数, 冒泡还是捕获)
var box = document.querySelector('.box') box.addEventListener('click', function () { console.log('我是第一个事件') },false) box.addEventListener('click', function () { console.log('我是第二个事件') },false)
° 当你点击 div 的时候, 两个函数都会执行, 并且会按照你注册的顺序执行
° 先打印 我是第一个事件 再打印 我是第二个事件
° 注意: 事件类型的时候不要写 on, 点击事件就是 click, 不是 onclick
• attachEvent :IE 7 8 下使用
• 语法: 元素. attachEvent('事件类型', 事件处理函数)
box.attachEvent('onclick', function () { console.log('我是第二个事件') }) box.attachEvent('onclick', function () { console.log('我是第二个事件') })
° 当你点击 div 的时候, 两个函数都会执行, 并且会按照你注册的倒序执行
° 先打印 我是第二个事件 再打印 我是第一个事件
° 注意: 这个需要些 on 方法
事件的传播
• 事件传播也称为事件流, 指的是事件的流向, 事件的执行顺序. 比如在一个大盒子里有一个小盒子, 都给他们绑定点击事件. 点击小盒子大盒子的事件也会被触发
• 这个就叫事件的传播
° 当元素触发一个事件的时候, 其父元素也会触发相同的事件, 父元素的父元素也会触发相同的事件
° 也就是说, 页面上任何一个元素触发事件, 都会一层一层最终导致 Windows 的相同事件触发, 前提是各 层级元素得有注册相同的事件, 不然不会触发
• 在事件传播的过程中, 有一些注意的点:
1. 只会传播同类事件
2. 只会从点击元素开始按照 html 的结构逐层向上元素的事件会被触发
3. 内部元素不管有没有该事件, 只要上层元素有该事件, 那么上层元素的事件就会被触发
冒泡和捕获
• 冒泡
° 就是从事件 目标 的事件处理函数开始, 依次向外, 直到 Windows 的事件处理函数触发
° 也就是从下向上的执行事件处理函数
• 捕获
° 就是从 Windows 的事件处理函数开始, 依次向内, 只要事件 目标 的事件处理函数执行
° 也就是从上向下的执行事件处理函数
阻止事件传播
• 如果想只触发当前点击对象的事件, 不想让外层的事件触发 , 可以使用不冒泡 e.cancelBubble=true 或不传播 e.stopPropagation()
var box = document.querySelector('.box') var atr = document.querySelector('.atr') box.onclick = function (e) { e.stopPropagation() // 不传播 console.log('我被点击了 box') } atr.onclick = function (e) { e.cancelBubble=true // 不冒泡 console.log('我被点击了 atr') }
事件委托
• 就是把我要做的事情委托给别人来做
• 因为我们的冒泡机制, 点击子元素的时候, 也会同步触发父元素的相同事件 , 所以我们就可以把子元素的事件委托给父元素来做
• 点击子元素的时候, 不管子元素有没有点击事件, 只要父元素有点击事件, 那么就可以触发父元素的点击事件
var box = document.querySelector('.box') var atr = document.querySelector('.atr') atr.onclick = function (e) { console.log('我被点击了 atr') } target
• target 这个属性是事件对象里面的属性, 表示你点击的目标
• 当你触发点击事件的时候, 你点击在哪个元素上, target 就是哪个元素
• 这个 target 也不兼容, 在 IE 下要使用 srcElement
var box = document.querySelector('.box') var atr = document.querySelector('.atr') atr.onclick = function (e) { var e = e || Windows.event //event 兼容写法 var target = e.target || e.srcElement //target 兼容写法 console.log(target) }
委托
• 这个时候, 当我们点击 box 里面的元素的时候, 也可以触发 box 的点事件
• 并且在事件内不, 我们也可以拿到你点击的到底是哪个对象
• 这个时候, 我们就可以把 li 的事件委托给 box 父级来做
var box = document.querySelector('.box') var atr = document.querySelector('.atr') atr.onclick = function (e) { var e = e || Windows.event //event 兼容写法 var target = e.target || e.srcElement //target 兼容写法 if(target.className=='atr'){ // 这里面就找到需要操作的元素 console.log(111) } }
最后我们想下, 为啥使用事件委托?
1. 提高性能和效率
2. 减少事件注册, 节省内存占用
3. 未来元素无需再次注册事件
4. 后面添加的元素也会有事件
默认行为
• 默认行为, 就是不用我们注册, 它自己就存在的事情
° 比如我们点击鼠标右键的时候, 会自动弹出一个菜单
° 比如我们点击 a 标签的时候, 我们不需要注册点击事件, 他自己就会跳转页面
• 这些不需要我们注册就能实现的事情, 我们叫做默认事件
阻止默认行为
• 有的时候, 我们不希望浏览器执行默认事件
º 比如我给 a 标签绑定了一个点击事件, 我点击你的时候希望你能告诉我你的地址是什么 , 而不是直接跳转链接
º 那么我们就要把 a 标签原先的默认事件阻止, 不让他执行默认事件
• 我们有两个方法来阻止默认事件
º e.preventDefault() : 非 IE 使用
° e.returnValue = false :IE 使用
• 我们阻止默认事件的时候也要写一个兼容的写法
var oA = document.querySelector('a') a.addEventListener('click', function (e) { e = e || Windows.event console.log(this.href) // 下面这个是兼容写法 e.preventDefault ? e.preventDefault() : e.returnValue = false })
来源: https://www.cnblogs.com/dcyd/p/12482989.html