>首页> IT >

最资讯丨深入解析JS中的事件对象Event

时间:2022-08-04 19:46:09       来源:转载
事件发生以后,会产生一个事件对象(Event),代表事件的状态。下面本篇文章就来带大家深入了解一下JS中的事件对象Event,对它做一个详细的解读,希望对大家有所帮助!

一、什么是事件对象 Event

每一个事件触发时,都会产生一个与之对应的事件对象 event,其中包含了触发事件的元素、键盘鼠标的状态、位置等等内容。


(资料图片)

每当用户触发一个事件后,JS 就会自动生成一个 event对象,根据触发事件的不同,这个对象包含的内容也不同,比如通过鼠标触发点击事件,会产生一个 MouseEvent对象,其中包含了鼠标的位置等内容;通过键盘触发事件,会产生一个 KeyboardEvent对象其中包含按键相关的信息。

event对象代表事件的状态,比如触发事件的元素、键盘按键的状态、鼠标的位置、鼠标按键的状态等等;event对象是一个隐式参数,并且只在事件发生的过程中才有效;event对象根据触发方式的不同会具有不同的属性,也就是说某些属性只对特定事件有效,但所有内容都是继承自 Event对象;

event对象在 IEChrome等浏览器表现不尽相同,例如说 event.target表示触发事件的元素,在 IE中需要使用 event.srcElement获取;

Event对象本身就是一个构造函数,可以用来生成新的实例。

event = new Event(type, options);

Event构造函数接受两个参数。第一个参数type是字符串,表示事件的名称;第二个参数options是一个对象,表示事件对象的配置。该对象主要有下面两个属性。

bubbles:布尔值,可选,默认为false,表示事件对象是否冒泡。

cancelable:布尔值,可选,默认为false,表示事件是否可以被取消,即能否用Event.preventDefault()取消这个事件。一旦事件被取消,就好像从来没有发生过,不会触发浏览器对该事件的默认行为。

var ev = new Event(  "look",  {    "bubbles": true,    "cancelable": false  });document.dispatchEvent(ev);

上面代码新建一个look事件实例,然后使用dispatchEvent方法触发该事件。

注意,如果不是显式指定bubbles属性为true,生成的事件就只能在“捕获阶段”触发监听函数。

// HTML 代码为// 

Hello

var div = document.querySelector("div");var p = document.querySelector("p");function callback(event) { var tag = event.currentTarget.tagName; console.log("Tag: " + tag); // 没有任何输出}div.addEventListener("click", callback, false);var click = new Event("click");p.dispatchEvent(click);

上面代码中,p元素发出一个click事件,该事件默认不会冒泡。div.addEventListener方法指定在冒泡阶段监听,因此监听函数不会触发。如果写成div.addEventListener("click", callback, true),那么在“捕获阶段”可以监听到这个事件。

另一方面,如果这个事件在div元素上触发。

div.dispatchEvent(click);

那么,不管div元素是在冒泡阶段监听,还是在捕获阶段监听,都会触发监听函数。因为这时div元素是事件的目标,不存在是否冒泡的问题,div元素总是会接收到事件,因此导致监听函数生效。

二、Event 属性

我们在前面提到,根据触发方式的不同 event对象会具有不同的属性,我们可以将其大体分为四部分:

通用属性(无论是通过键盘还是鼠标触发都拥有的属性)

bubbles事件是否会冒泡,布尔值;

cancelable事件是否具有默认行为,布尔值;   默认行为指的是浏览器中规定的一些行为,比如 标签点击后会跳转链接,

标签内按回车会自动提交等等。

currentTarget事件处理程序当前正在处理事件的那个元素,返回一个 Element对象;

defaultPrevented事件是否取消了默认行为,布尔值;

detail返回一个包含事件详细信息的数字   在 clickmousedownmouseup事件中,该数字表示当前的点击次数, dblclick事件中,该数字一直为 2 。在键盘事件和鼠标经过事件中,该数字一直为0。

eventPhase返回一个代表事件处理程序发生时所在阶段的数字;   0表示当前阶段未发生其他事件;1表示当前事件在捕获阶段发生;2表示当前事件处于目标阶段;3表示当前事件处于冒泡阶段;

isTrusted表示该事件是由用户行为触发的,还是由 JS 代码触发的,布尔值;   当事件是由用户行为(点击等)触发时,值为 true,当事件是通过 EventTarget.dispatchEvent()派发的时候,这个属性的值为 false

  • 列表1
  • 列表2
  • 列表3
  • 列表4
<script> document.querySelector("ul").addEventListener("click", fn1, true) document.querySelector("ul").addEventListener("click", fn1, false) document.querySelector("li").addEventListener("click", fn1, true) function fn1() { console.log(this);// 打印当前事件对象 console.log(event.eventPhase);// 打印 }</script>

点击列表1后,控制台打印如下结果:

target返回触发该事件的目标节点,返回一个 Element对象;   target并不一定与 this指向相同,this指向的是当前发生事件的元素,而 target指向的是触发该事件的元素,可以将上方代码中的 console.log(event.eventPhase);换成 console.log(event.target);来具体体验一下两者的不同。   在 IE浏览器中应使用 srcElement来代替 target

type返回触发的事件名称,例 clickkeydown等;

鼠标属性

button当事件被触发时,哪个鼠标按钮被点击;clientX当事件被触发时,鼠标指针的 x 轴坐标;clientY当事件被触发时,鼠标指针的 y 轴坐标;screenX当事件被触发时,鼠标指针的 x 轴坐标;screenY当事件被触发时,鼠标指针的 y 轴坐标;

键盘属性

altKey当事件被触发时,“Alt” 是否被按下;ctrlKey当事件被触发时,“Ctrl” 是否被按下;metaKey当事件被触发时,“meta” 是否被按下;shiftKey当事件被触发时,“Shift” 是否被按下;Location返回按键在设备上的位置;charCode当事件被触发时,触发键值的字母代码;key按下按键时返回按键的标识符;keyCode返回 keypress事件触发的键的值的字符代码,或者 keydownkeyup事件的键的代码;which返回 keypress事件触发的键的值的字符代码,或者 keydownkeyup事件的键的代码;relatedTarget返回与事件的目标节点相关的节点。

IE属性

cancelBubble如果想阻止事件冒泡,必须把该属性设为 truefromElement对于 mouseovermouseout事件,fromElement引用移出鼠标的元素;returnValue等同于 defaultPreventedsrcElement等同于 targettoElement对于 mouseovermouseout事件,该属性引用移入鼠标的元素;x事件发生的位置的 x 坐标;y事件发生的位置的 y 坐标;

三、Event 方法

initEvent()初始化新创建的 Event对象的属性;preventDefault()阻止触发事件元素的默认行为;stopPropagation()阻止事件冒泡;

如果想要阻止事件元素的默认行为,例如点击 标签时执行点击事件,不要跳转链接,需要在事件处理程序中调用 preventDefault方法:

百度一下,你就知道<script>document.querySelector("a").onclick = function () {event.preventDefault();//do something}</script>

如果想要阻止事件冒泡,例如点击子元素标签时执行子元素的点击事件,而不想要执行父级元素的事件处理程序,则需要调用 stopPropagation方法:

  • 不要触发 ul 的点击事件处理程序
<script>document.querySelector("ul").onclick = function () {alert("事件冒泡,触发 ul 的点击事件")}document.querySelector("li").onclick = function () {event.stopPropagation();// do something}</script>

其他相关方法

addEventListener()给目标元素注册监听事件;createEvent()创建一个 Event对象;dispatchEvent()将事件发送到目标元素的监听器上;handleEvent()把任意对象注册为事件处理程序;initMouseEvent()初始化鼠标事件对象的值;initKeyboardEvent()初始化键盘事件对象的值;initMutationEvent()初始变动事件和 HTML事件对象的值;initCustomEvent()初始自定义事件对象的值;removeEventListener()删除目标元素上的某个监听事件;

另外关于 createEvent方法,根据传入参数的不同,会返回不同的 event对象:

MouseEvents创建鼠标事件对象,返回的对象中包含 initMouseEvent()方法;KeyboardEvent创建键盘事件对象,返回的对象中包含 initKeyEvent()方法;KeyEventsfirefox中创建键盘事件对象需要传入该参数;MutationEvents模拟变动事件和 HTML 事件的事件对象,返回的对象中包含 initMutationEvent方法;CustomEvent创建自定义事件对象,返回的对象中包含 initCustomEvent()方法;

四、模拟事件

4.1 模拟鼠标事件

我们可以通过 createEvent()方法可以创建一个新的 event对象,借助 initMouseEvent()方法来对这个鼠标事件对象的值进行初始化,该方法接受十五个参数,分别与鼠标事件中的各个属性一一对应,按照 typebubblescancelableviewdetailscreenXscreenYclientXclientYctrlKeyaltKeyshiftKey、、metaKeybuttonrelatedTarget的顺序传入即可:

var oBtn = document.querySelector("button");// 为 button 绑定事件处理程序oBtn.addEventListener("click", function () {    console.log(event);})var event = document.createEvent("MouseEvents");// 通过 initMouseEvent() 方法初始化鼠标事件的 event 对象event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, null);// 通过 dispatchEvent() 方法来触发 oBtn 上绑定的点击事件,此时浏览器打印的 event 对象为自定义的 eventoBtn.dispatchEvent(event);

初始化事件对象时,最重要的是前四个参数,因为浏览器在触发事件时,这四个参数是必须的,而剩余的参数只有在事件处理程序中才会被使用,target会在执行 dispatchEvent方法时自动赋值;

4.2 模拟键盘事件

同样需要先使用 createEvent()方法可以创建一个新的 event对象,但需要使用 initKeyEvent来对键盘事件对象的值进行初始化,该方法接收八个参数,分别于键盘事件对象中的各个属性一一对应,按照 typebubblescancelableviewkeylocationmodifiersrepeat的顺序传入即可。但在 firefox中,需要按照 typebubblescancelableviewctrlKeyaltKeyshiftKeymetaKeykeyCodecharCode` 的顺序传入十个参数

document.onkeydown = function () {    console.log(event);}var event = document.createEvent("KeyboardEvent");event.initKeyboardEvent("keydown", false, false, document.defaultView, "a", 0, "Shift", 0);document.dispatchEvent(event);

4.3 模拟其他事件

如果想要模拟其他事件,诸如 submitfocusHTML和变动事件,则需要通过 MutationEvents方法来创建事件,通过 initEvent方法来进行初始化,按照typebubblescancelablerelatedNodepreValuenewValueattrNameattrChange的顺序传入参数。

<script>    var oInput = document.querySelector("input");    oInput.addEventListener("focus", function () {        this.style.background = "#ccc"    })    var event = document.createEvent("HTMLEvents");    event.initEvent("focus", true, false);    oInput.dispatchEvent(event);</script>

4.4 自定义 DOM 事件

自定义事件不是由 DOM 原生触发的,它的目的是让开发人员创建自己的事件。要创建新的自定义事件,可以调用 createEvent("CustomEvent"),返回的对象有一个名为 initCustomEvent()的方法,接收 typebubblescancelabledetail四个参数。

var oInput = document.querySelector("input");oInput.addEventListener("myEvent", function () {console.log(event);})var event = document.createEvent("CustomEvent");event.initCustomEvent("myEvent", true, false, "自定义事件myEvent");oInput.dispatchEvent(event);

上方代码创建了一个自定义事件,事件名为 myEvent, 该事件可以向上冒泡,不可以执行在浏览器中的默认行为, detail属性的值为 自定义事件myEvent,可以在绑定该事件的元素或者元素的父级元素上绑定事件处理程序来查看 event对象。

五、Event的兼容性处理

主要考虑到 IE浏览器与 Chrome等浏览器事件对象的区别,针对下面四个属性,需要进行特殊处理:

获得 event对象var event = event || window.event;

获得 target对象var target = event.target || event.srcElement;

阻止浏览器默认行为event.preventDefault ? event.preventDefault() : (event.returnValue = false);

阻止事件冒泡event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);

【相关推荐:javascript学习教程

以上就是深入解析JS中的事件对象Event的详细内容,更多请关注php中文网其它相关文章!

关键词: 事件对象 事件处理 触发事件