JS 事件
事件是元素(或者浏览器)天生自带的行为,只要行为处罚,就会触发相关的事件
xxx.onclick = function(){} 属于事件绑定,给这个事件行为绑定方法,行为触发的时候
事件参考文档
【事件】
- 鼠标事件
- click 点击
- dbclick 双击
- mousedown/mouseup/mousemove
- mouseover/mouseout
- mouseenter/mouseleave
- wheel 滚轮
- 表单事件
- focus/blur 获取、失去焦点
- change 内容改变
- 键盘事件
- keyup/keydown
- keyepress
- 手势事件
- touchstart/touchend/toucemove 单指
- gesture 多指事件
- 拖放事件
- dragstart / drag / dragend
- dragenter 进入投放区
- dragover/dragover
- drop 释放
- 媒体事件
- 值变化事件
- hashchanghe 浏览器地址栏 hash 变化触发事件
- input 表单正在输入内容。。。
- 其他事件
- offline/online 断网或者连网
- animationstart/iteration CSS3Animation 动画事件
- transitionstart/end。run CSSTranslation 动画事件
- fullscreenchange 全凭切换事件
- resize 窗口大小改变
- scroll 滚动条滚动
- load 加载完
- error 加载失败
- timeout 加载超时
- progress 加载中
【事件绑定】
- 1、DOM0 级事件绑定
元素.onxxx = function(){...} - 2、DOM2 级事件绑定
在 EventTarget.prototype 添加了 addEventListener/removeEventLister/dispatchEvent
非标准浏览器(IE<=8)没有这个东西,只有 attachEvent/datachevent(里面 this 不是当前元素)
xxx.addEventListener('xxx',function(){...})
【DOM 事件绑定原理】
每一个 DOM 元素对象内都有很多内置属性,其中包含 onxxx 这样的事件类型的私有属性
DOM0事件绑定原理就是给这些事件类私有属性赋值
特点: 如果不存在不绑定,只能绑定一个方法
DOM2 事件绑定
box.addEventListener('click',function(){})
DOM2 事件可以绑定多个,他是通过浏览器事件池机制来做的
问: window.onload 和 document.ready 区别($(document).ready())?
答: jq 中的 document.ready 的原理是使用了 DOM2 级事件绑定,通过
window.addEventlistener("DOMContentLoad", ()=>{...}) 可以在一个页面中执行多次这个方法,而且它是 DOM 加载完后执行
window.onload 是基于 DOM0 级事件绑定,只能在页面初始的时候执行一次,而且需要所有资源加载完后才执行,所以 window.addEventlistener("DOMContentLoad", ()=>{...})比 window.onload 执行的更快
事件对象和事件传播机制
- 事件对象
当事件触发、浏览器会把制定的方法执行,并且把全局下记录的当前操作信息的'事件对象'传递给这个函数 ,不管在哪个函数中,获取到的是同一个对象,存储的是当前操作的信息,和函数没关系
let n; document.bofy.onclick = function (ev) { console.log("Body"); console.log(ev === n); }; box.onclick = function (ev) { console.log("Box"); console.log(ev); };
事件对象
- 【鼠标事件对象】MouseEvent
clientX/clientY: 鼠标触发点距离当前窗口左上角x/y坐标
pageX/pageY:鼠标触发点距离当前页面Body的左上角x/y坐标
path:[...]: 存储的是冒泡阶段传播的路径,(值是捕获阶段获得的)
srcElement/target: 事件源,当前操作的元素,在哪触发的
type: 事件类型 - 【键盘事件对象】KeyboardEvent
which/keyCode 键盘码
altKey/shiftKey/ctrlKey 记录是否在按键的时候按了,组合按键,属性是布尔 - 【常规事件对象】Event
e.preventDefault() / e.returnValue 阻止事件默认行为
```js // 设置点击ctrl+f 刷新 document.onkeydown = function (ev) { console.log(ev); ev.preventDefault() || ev.returnValue; let { ctrlKey, keyCode } = ev; if (ctrlKey && keyCode === 70) { window.location.reload(); } }; // 禁止右键打开菜单 document.oncontextmenu = function (ev) { ev.preventDefault() // return false }; ```
- e.stopPropagation() / e.cancelBubble 阻止事件的冒泡
// 事件具备传播机制 + 捕获阶段 CAPTURING_PHASE: 1 + 目标 AT_TARGET: 2 + 冒泡 BUBBLING_PHASE 1、当我们触发当前元素的事件行为的时候,首先从最外层window开始,一层层的按照结构向里层查找 —— 捕获阶段(目的是为冒泡提供传播路径) 2、找到当前的事件源,触发当前的相关行为 —— 目标阶段 3、不仅当前事件源的相关行为被触发,其所有祖先元素的相关事件行为都会被触发,(由里向外) —— 冒泡阶段 ⚠️注意:DOM0级事件中只有冒泡事件,DOM2级事件中xxx.addEventListener('click',function(){}, false) , 第三个参数是可以控制在冒泡还是捕获阶段触发,默认false,冒泡,改成true为捕获阶段,但是很少用 ⚠️:大部分时间默认就存在冒泡机制,但是少部分事件天生就自己阻止了冒泡传播 mouseenter/mouseleave // 进入离开 默认阻止了冒泡传播 mouseover/mouseout // 悬浮 没有阻止冒泡 很恶心 最好不用 或者阻止冒泡事件
- 【手指事件对象】TouchEvent
- ...
- 事件对象中常用的属性
- target & srcEvent
- type
- code & key
- keyCode & which
- which/keyCode
- clientY/clientX
- pageX/pageY
- preventDefault
- stopPropagation