事件

79 阅读3分钟

Js 的事件循环(Event Loop)机制以及实例讲解

事件机制.jpg 参照文章:juejin.cn/post/684490…

所有事件类型的实例的原型链:

document.body->HTMLBodyElement.prototype->HTMLElement.prototype->Element.prototype->Node.prototype->EventTarget.prototype->Object.prototype;

WheelEvent.prototype->MouseEvent.prototype->UIEvent.prototype->Event.prototype->Object.prototype;

MouseEvent.prototype->UIEvent.prototype->Event.prototype->Object.prototype;

KeyboardEvent.prototype->UIEvent.prototype->Event.prototype->Object.prototype;

CustomEvent.prototype->Event.prototype->Object.prototype;

事件流包括事件捕获、到达目标元素、事件冒泡三个阶段。比如ie早期的版本是不支持事件捕获阶段的,通常事件捕获也是主要用于一些拦截操作。在事件委托时考虑到兼容性会通过事件冒泡阶段实现。

事件处理程序添加方式分为一下几种类型:

1.可以直接在模板标签里通过作为“on+事件名”的属性值的方式添加事件处理程序;

2.DOM0中通过"dom节点.on+事件名=function(){}"的方式添加事件处理程序;从语法本质上来说和直接在标签里添加是一样的;移除事件处理程序的方式:"dom节点.on+事件名=null"

3.DOM2中是通过“dom节点的addEventListener("事件名",事件处理程序,是否冒泡布尔值)”添加事件处理程序的;是通过“dom节点的removeEventListener("事件名",事件处理程序,是否冒泡布尔值)”移除事件处理程序的。ie事件处理程序是通过attachEvent("事件名",事件处理程序)和detachEvent("事件名",事件处理程序)来添加、移除事件处理程序,但ie中事件处理程序的this指向window,可以在没有传参的事件处理程序中通过window.event属性访问event对象,并且触发的顺序是逆向的。

事件对象:

每一个事件处理程序函数都有一个事件对象event参数,不同类型的事件event中的属性略有差异,event包含了有关此事件的所有信息,此对象也是事件模拟中创建的事件对象。事件对象event照样遵循原型链继承原则,可以查看原型链上的继承关系。

常用的方法:event.preventDefault()阻止事件默认行为、event.stopPropagation()阻止事件捕获冒泡行为、event.eventPhase事件处于事件的哪个阶段。

事件类型分类:

用户界面事件:涉及与bom交互的通用浏览器事件。beforeunload页面卸载前事件。pageshow、pagehide往返缓存页面事件。

鼠标事件:

mouseover和mouseout在子元素中也会触发。mousedown>mouseup>click>mousedown>mouseup>click>dbclick。滚轮事件mousewheel也是继承自鼠标事件。 contextmenu:单击鼠标右键事件。 xy.jpg

键盘事件:

keypress只在有字符输入时会被触发,DOM3 Events被textInput替代。keydowm>keypress>keyup;

触摸屏幕事件和手势事件:

touchstart、touchmove、touchend触摸事件,touchstart>mouseover>mousemove>mousedown>mouseup>click>touchend;

gesturestart、gesturechange、gestureend手势事件,touchstart>gesturestart>gestureend>touchend;

事件引起的内存性能优化:

由于事件的绑定会占用一定的内存,过多的事件绑定会导致一定的性能下降,所以我们可以使用事件委托的方式来降低绑定事件占用的内存。 当一个被绑定事件的dom节点被删除或者卸载一个页面,如果被绑定的事件处理程序没有移除,那么这个节点占用的内存无法顺利的被回收,导致内存泄漏;所以我们在删除节点或者卸载页面前要先移除相应的事件处理程序,防止内存泄漏。

事件模拟:

通常情况事件都是用户触发或者浏览器触发,其实事件还可以通过js代码触发,这就是事件模拟。

事件模拟分为创建事件、事件初始化、事件触发三个步奏:事件类型名称和事件绑定的处理程序是分开的,和事件对象不是分开的。

let event = document.createEvent("Event/UIEvent/MouseEvent/keyboardEvent/HTMLEvent/CustomEvent");

event.initEvent()/event.initMouseEvent()/event.initKeyboardEvent()/event.initCustomEvent();

dom.dispatchEvent(event);

IE事件模拟:事件类型名称和事件绑定的处理程序是分开的,和事件对象也是分开的。

let event = document.createEventObject();

通过事件给对象属性赋值的方式初始化:event.screenX=100.......

btn.fireEvent("on+事件类型名称",event);