JS浏览器事件
js浏览器常见事件,可在MDN中查阅相关使用方法
https://developer.mozilla.org/zh-CN/docs/Web/Events
1、什么是浏览器事件呢?
事件是浏览器天生就具备的行为,不论我们是否基于JS代码绑定方法,只要相关的行为触发,则一定会触发相关的事件
理解:
比如说 box.onclick 并不是因为box绑定了click方法才具备的点击事件。click事件本身就是存在的,只要我们点击了box就会出发点击事件。
2、浏览器有哪些事件行为?
常见事件行为:
- 【鼠标事件】
* mouseover 鼠标经过* mouseout 鼠标离开* mouseenter 鼠标进入* mouseleave 鼠标离开* mousemove 鼠标移动* mousedown 鼠标按下* mouseup 鼠标抬起* click 点击(点几次触发几次)* dblclick 双击(在300MS内连续触发两次点击,则认为是一次双击)* mousewheel 鼠标滚轮滚动* contextmenu 鼠标右键点击* ......
- 【键盘事件】
* keydown 按键按下* keyup 按键抬起* keypress 按键长按* input 文本框内容输入中(改变中)* ......
【其它事件】
* change 内容改变* blur 文本框失去焦点* focus 文本框获取焦点* scroll 滚动条滚动事件* submit 表单提交中的提交事件* resize 大小改变* load 加载(加载完成)事件* error 加载失败事件* DOMContentLoaded DOM结构加载完成* drag/dragstart/dragend... H5中新增的拖拽的相关事件* ......
- 【移动端事件】
* [touch单手指操作模型]* touchstart 手指按下* touchmove 手指移动* touchend 手指离开* touchcancel 因为意外情况导致操作结束* [gesture多手指操作模型]* gesturestart/gestureend/gesturechange...* ......
3、事件绑定,什么是事件绑定
事件绑定:给元素的某个事件行为绑定方法,这样事件行为触发的时候,对应绑定的方法会执行,完成一些需要完成的功能
事件绑定分为:DOM0级事件绑定和 DOM2级事件绑定
* DOM0级事件绑定:元素.onxxx=function(){}* DOM2级事件绑定:* [标准浏览器]* 元素.addEventListener('xxx',function(){},false)* [IE6~8]* 元素.attachEvent('onxxx',function(){})
4、DOM0 VS DOM2 那种事件绑定好呢?
1) DOM0事件绑定
1.事件绑定的原理就是给当前元素对象的某些私有属性(基于事件/onxxx)赋值一个函数,当事件行为触发,浏览器会帮助把绑定的方法执行
box.onclick = function () {}
=>移除事件绑定: box.onclick=null;
=>这样只能给当前元素的某个事件行为绑定一个方法(绑定多个方法会把之前绑定的替代掉)
=>如果元素私有属性中不具备某个事件的私有属性(例如:ontransitionend/onDOMContentLoaded…)则无法给这些事件绑定方法
2) DOM2事件绑定
1.基于元素的原型链找到EventTarget.prototype,使用内置的addEventListener或者removeEventListener进行事件绑定和移除事件绑定
2.底层原理是基于浏览器内置的事件池机制完成事件监听和方法绑定的
=> 可以给当前元素的某个事件类型绑定多个不同的方法,事件触发会按照绑定的顺序把方法依次执行
=> 所有浏览器支持的事件类型都可以做事件绑定
box.addEventListener('transitionend',func)

5、真实项目开发中哪种绑定事件用的比较多?
真实开发过程中,DOM0和DOM2可以共存(不会冲突),而且一般以用DOM2偏多一些,因为其机制相对比较完善;而且类似于JQ这种类库或者一些常用的插件,基本上也是基于DOM2事件绑定封装事件处理方法的;
6、经典面试题
window.onload 和 document.ready(JQ:$(document).ready())的区别?
-
window.onload是等待所有资源都加载完成才会触发执行,而我之前研究过部分JQ源码,发现
$(document).ready()用的是DOMContentLoaded事件,事件本身是DOM结构加载完成就会触发执行,所以$(document).ready()要优先于window.onload触发 -
window.onload是基于DOM0事件绑定,只能绑定一个方法,所以页面中
只能用一次;而JQ中的事件绑定都是基于DOM2完成的,所以可以在相同页面中绑定多个不同方法,也就是用很多次,我之前在JQ开发中,经常把编写的模块代码放到$(function(){})这里,既能形成闭包,还能保证DOM结构加载完才会执行 -
不论哪一种办法都是为了保证DOM结构加载完再执行的,这样在方法中肯定能获取到DOM元素,防止把JS放到DOM之前加载,导致元素无法获取的问题(引申出来的问题:JS/CSS/IMG/结构加载的顺序和机制 =>浏览器渲染机制)
DOM2事件绑定的时候,我们一般不绑定匿名方法(以方便后期的移除),因为移除的时候需要根据事件和方法去移除
function fn1() {}
function fn2() {}
function fn3() {}
box.addEventListener('click', fn1);
box.addEventListener('click', fn2);
box.addEventListener('click', fn2);
box.addEventListener('mouseenter', fn1);
box.addEventListener('dblclick', fn3); */
MouseEvent鼠标事件对象
box.onclick = function (ev) {console.log(ev);=>MouseEvent鼠标事件对象};
type:事件类型 “click”
target:事件源 触发的元素 srcElement
clientX/clientY:当前鼠标触发点距离当前窗口左上角的X/Y轴坐标
pageX/pageY:当前鼠标触发点距离当前页面BODY左上角的X/Y轴坐标 不兼容IE低版本浏览器
ev.preventDefault() 阻止默认行为 兼容处理 ev.returnValue=false
ev.stopPropagation() 阻止它的冒泡传播 兼容处理 ev.cancelBubble=true
键盘事件对象
document.onkeydown = function (ev) {console.log(ev); };
// KeyboardEvent 键盘事件对象
// keyCode/which:获取键盘码
// 空格键 32
// ENTER 13
// BACKSPACE 8
// DEL 46
// SHIFT CTRL ALT:16 17 18
// 四个方向键:左 37 上 38 右 39 下 40
普通事件对象
window.onload = function (ev) {console.log(ev);// Event 普通事件对象};
box.ontouchstart = function (ev) {console.log(ev);};
// TouchEvent手指事件对象
// touchs/changedTouches:touchs只能获取手指在屏幕上的时候的信息,如果手指离开,信息就没了,而changedTouches相对于touchs来讲可以获取到手指离开前的信息,所以项目中用changedTouches最多
// 获取第一个手指信息,这里存储了clientX等基本信息
let point = ev.changedTouches[0];
6、阻止默认行为
// 默认行为:很多元素天生具备一些默认的行为// 1. A标签我们点击的时候会实现页面的跳转(锚点定位)// 2. 文本框输入的时候可以输入内容// 3. 部分情况下文本框会存在输入记忆 // 4. 鼠标按右键出现右键菜单
window.oncontextmenu = function (ev) {ev.preventDefault();// 接下来自己可以构建一个属于自己的右键菜单// ...}; link.onclick = function (ev) {// 点击A的时候先触发CLICK再去跳转(在此处阻止默认行为它也就不跳转了)ev.preventDefault();};
7、事件的传播机制
* AT_TARGET: 2 目标阶段* BUBBLING_PHASE: 3 冒泡阶段* CAPTURING_PHASE: 1 捕获阶段* NONE: 0
当前元素的某个事件行为被触发,一定会经历三个阶段
1) 捕获阶段:从最外层容器一直向里层查找,直到找到当前触发的事件源为止,查找的目的是建立起当前元素未来冒泡传播的传播路线 (外向里)
2) 目标阶段:把当前元素的相关事件行为触发(如果绑定了方法,则把方法执行)
3) 冒泡阶段:不仅当前元素的相关事件行为被触发,而且在捕获阶段获取的传播路径中的每一个元素的相关事件行为都会被触发[顺序从内到外](而且其父级所有元素的相关事件行为也会被触发),如果也对应绑定了方法,方法也会被触发执行
window -> document -> HTML -> BODY -> OUTER -> INNER -> CENTER
DOM0事件绑定,绑定的方法都是控制在目标或者冒泡阶段执行;
DOM2可以控制在捕获阶段执行(xxx.addEventListener(‘xxx’,xxx,true) 最后
参数TRUE就是控制在捕获阶段执行,只不过一般都不用)
举例子:
// 一次点击,执行了四个方法,每个方法中都有EV事件对象,此时四个对象是同一个;事件对象和在哪个方法中出现没有关系,事件对象是用来记录当前操作的相关信息的,也就是操作一次记录一次,此时不论在哪获取的EV都是记录本次操作的信息,除非重新操作,那么上一次信息就没有了,EV存储的是最新的操作信息!
document.body.onclick = function (ev) {console.log("BODY", ev);};outer.onclick = function (ev) {console.log("OUTER", ev);};inner.onclick = function (ev) {console.log("INNER", ev);};center.onclick = function (ev) {console.log("CENTER", ev);// 阻止冒泡传播ev.stopPropagation();};
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
