JavaScript异步编程之事件

简介:

DOM0

html标签中的写法

<image id="element" src="hello.png" onclick="alert('Hi')"/>
复制代码

在JS中的绑定方法:

var element = document.getElementById("element");
element.onclick = function(e) {}
复制代码

dom0是节点元素的私有属性。同一个事件只能绑定一个,绑定多个,只有最后一个有效。直接写在html节点上的也会被覆盖。如下面的代码,最后点击触发的时候只会打印3。

var element = document.getElementById("element");
element.onclick = function(e) {console.log(1)};
element.onclick = function(e) {console.log(2)};
element.onclick = function(e) {console.log(3)};
复制代码

所以,在使用如window.onload之类的事件的时候就需要注意了。

DOM1

有标准,不涉及实践。

DOM2

addEventListener方法在节点对象的原型链上。绑定实名函数更好,因为可以移除。第三个参数用于选择在什么阶段触发,默认false表示在冒泡阶段触发。

element.addEventListener('change',function(){},false)
复制代码

与DOM0的相比,DOM2事件可以绑定多个,如下,1和2都会被打印:

element.addEventListener('change', function() {console.log(1)}, false);
element.addEventListener('change', function() {console.log(2)}, false);
复制代码

可是,在绑定实名函数的时候,如果事件、函数名和触发阶段完全相同的话,最终也是只有最后一个有效,如下,最终事件触发的时候只会打印出一个1:

function fn() {console.log(1)};
element.addEventListener('change', fn, false);
element.addEventListener('change', fn, false);
复制代码

此外,addEventListener还可以绑定DOM0中没有的事件,如DOMContentLoaded。

DOM3

与DOM2的区别在于事件的种类,其他的一样。如keyupkeydownkeypress都是DOM3的事件,click也是DOM3级事件,具体到MDN中搜索DOM L3

事件流

简要的说就是事件的三个阶段:捕获阶段--目标阶段--冒泡阶段。详细说就是如下图。

1

当用户点击浏览器窗口,事件发生,捕获阶段开始:window--document--html--body--父节点--目标节点(目标阶段),然后开始冒泡阶段:目标节点--父节点--body--html--document--window。

几个需要注意的api

preventDefault的作用是阻止浏览器默认行为,什么是默认行为?除了你自己绑定的操作之外的行为都是浏览器的默认行为,如a标签的跳转,表单的提交,鼠标右键呼出菜单等等。

此外event.returnValue = false;return false;也可以达到跟proventDefault同样的效果。如果是a标签,阻止跳转,可以href="javascript:;"href=javascript:void 0;

stopPropagation的作用是阻止事件的传播。阻止的是其他节点上的事件。

stopImmediatePropagation的作用也是阻止事件的传播。它不但能阻止其他节点上的事件,当前节点上的其他未触发的事件也会一并阻止。如下代码,只打印1:

element.addEventListener('click', function(event) { 
  event.stopImmdiatePropagation();
  console.log(1);
}, false);
element.addEventListener('click', function() {console.log(2)}, false);
复制代码

currentTarget,当前会执行的回调函数绑定的那个节点。

elementFirst.addEventListener('click', function(event) {
  console.log(event.currentTarget);		// elementFirst
}, false);
elementSecond.addEventListener('click', function(event) {
  console.log(event.currentTarget);		// elementSecond
}, false);
复制代码

target,就是事件流中的目标阶段的那个节点,也就是目标节点。需要注意的是,事件是否发生与是否绑定的操作没有关系,即便没有在一个节点上绑定事件的操作,事件依然会发生。target可以在事件委托中使用。

自定义事件

var myEvent = new Event('theEvent');
theTarget.addEventlistener('theEvent', function() {doSomething()})
theTarget.dispatchEvent(myEvent);	// theTarget是一个节点,或者说是一个可以调用addEventListener方法的对象。
复制代码

此外customEvent做到跟Event同样的效果,他们的区别在于,customEvent可以加一些自己需要的数据进去,不过兼容性没有Event好。

Event创建了实例之后,也可以用myEvent.data = {}的方式给数据,效果是一样的。

这有什么用?可以用来做全局范围内的广播,使模块间解耦。在vue中有一个用于组件间通讯的EventBus,自定义事件就可以用来实现这一功能。

事件委托和代理

事件委托就是把本来应该由你来做的事情,让别人帮忙做一下。

在实际编程中,可能会出现这样的场景,一个节点下有多个子节点,每个子节点都要有相应的事件绑定,这个时候我们就可以利用事件的冒泡,把事件绑定在父节点上,然后用event.target来区分到底是哪个子节点触发的事件。当这些子节点需要动态增减的时候,使用事件委托就显得尤为方便了,无论是写代码的效率还是程序运行的效率都会更高。

局限性:focus、blur这样的事件没有在冒泡机制,无法委托。另外一些消耗较高的事件如mousemove和mouseout也不适合委托。如下图

1

如果我们把B区域的mousemove事件委托到A区域,当事件在A区域发生的时候,对应的操作也会执行,如果是消耗较低的事件,就不会有太大的影响,可如果是消耗较高的事件,就会显得有点浪费了。

观察者模式与发布订阅模式

这两种设计模式与事件非常的类似。与事件的区别在于,事件是异步的,而我们自己实现的这两种模式,虽然使用了回调函数,但大都是同步的。而这两种设计模式之间的区别在于,发布订阅模式的事件池是统一的,观察者模式的事件池分散在各个发布者上面。



原文发布时间为:2018年06月23日
原文作者:砖用冰西瓜
本文来源掘金如需转载请联系原作者

相关文章
|
19天前
|
JavaScript 前端开发
js开发:请解释事件冒泡和事件捕获。
JavaScript中的事件处理有冒泡和捕获两种方式。事件冒泡是从子元素向上级元素传递,而事件捕获则从外层元素向内层传递。`addEventListener`的第三个参数可设定事件模式,`false`或不设为冒泡,`true`为捕获。示例代码展示了如何设置。
24 2
|
12天前
|
JSON 前端开发 JavaScript
【JavaScript技术专栏】JavaScript异步编程:Promise、async/await解析
【4月更文挑战第30天】JavaScript中的异步编程通过Promise和async/await来解决回调地狱问题。Promise代表可能完成或拒绝的异步操作,有pending、fulfilled和rejected三种状态。它支持链式调用和Promise.all()、Promise.race()等方法。async/await是ES8引入的语法糖,允许异步代码以同步风格编写,提高可读性和可维护性。两者结合使用能更高效地处理非阻塞操作。
|
2天前
|
JavaScript 前端开发 UED
在 JavaScript 中,异步编程和回调函数是处理非阻塞操作(如网络请求、文件读写等)的重要工具
【5月更文挑战第10天】JavaScript中的异步编程和回调函数用于处理非阻塞操作,提高应用响应性和吞吐量。异步编程通过回调函数、Promises和async/await等方式实现,避免程序因等待操作完成而阻塞。回调函数是异步操作完成后调用的函数,常用于处理网络请求等。然而,回调函数存在嵌套问题和错误处理困难,因此出现了Promises和async/await等更优解决方案。
10 3
|
5天前
|
JavaScript 前端开发 开发者
javascript事件大全
javascript事件大全
10 1
|
5天前
|
JavaScript 前端开发
Javascript的一些监听事件
Javascript的一些监听事件
11 2
|
5天前
|
JavaScript 前端开发
js的事件介绍
js的事件介绍
11 1
|
5天前
|
JavaScript 前端开发
js的事件
js的事件
11 1
|
6天前
|
JavaScript 前端开发
js的交互事件
js的交互事件
12 1
|
9天前
|
JavaScript 前端开发 C++
【Web 前端】JavaScript window.onload 事件和 jQuery ready 函数有何不同?
【5月更文挑战第2天】【Web 前端】JavaScript window.onload 事件和 jQuery ready 函数有何不同?
|
12天前
|
JavaScript 前端开发 开发者
【JavaScript技术专栏】JavaScript事件处理机制详解
【4月更文挑战第30天】本文探讨JavaScript中的事件处理机制,涉及事件类型(如click、mouseover)、事件流(冒泡型、捕获型及目标阶段)、事件处理函数(内联与addEventListener方法)以及事件委托(用于优化内存和处理动态元素)。此外,还介绍了事件取消,通过`preventDefault()`和`stopPropagation()`控制事件行为。理解这些概念对构建交互式Web应用至关重要。