事件与事件处理器

187 阅读3分钟

浏览器执行环境的核心思想基于:同一时刻只能执行一个代码片段,即所谓的单线程模型。

例如在银行柜台前排队,每个人进入一只队伍等待叫号并“处理”。但Javascript只开启了一个营业柜台!每当轮到每个顾客时(某个事件)只能处理该位顾客


所有已生成的事件(无论是用户生成的,例如鼠标移动或键盘按压,还是服务器生成的,例如ajax事件)都会放在同一个事件队列中,以他们被浏览器检测到的顺序排列

事件处理的过程可以描述为一个简单的流程图

1:浏览器检查事件队列头

2:如果浏览器没有在队列中检测到事件,则继续检查

3:如果浏览器在队列中检测到了事件,则取出该事件并执行相应的事件处理器(如果存在),在这个过程中,余下的事件在事件队列中耐心的等待,直到轮到他们被处理

由于一次只能处理一个事件,所以必须格外注意处理所有事件的总时间,执行需要花费大量时间执行的事件处理函数会导致web应用无响应!!!

web应用的周期从用户指定某个网址(或单机某个链接)开始,由两个步骤组成:页面构建事件处理

1:输入url(或单击链接)

2:生成请求并发送至服务器

3:执行某个动作或获取某个资源,将相应发送回客户端

4:处理HTML CSS 和JavaScript并构建结果页面

5:监听事件队列,每次处理一个事件

6:与页面元素交互


注册事件处理器

1:通过把函数赋值给某个特殊属性

2:通过使用内置addEventListener方法

例如:将一个函数赋值给window对象上的某个特定属性onload:

window.onload = function () { }

通过这种方式,事件处理器就会注册到load事件上(当DOM已经就绪并全部构建完成,就会触发这个事件)但是并不推荐使用这种方式注册事件处理器,因为这种方式会带来缺点:对于某个事件只能注册一个事件处理器,也就是说一不小心会将上一个事件处理器改掉,而addEventListener方法能够让我们注册尽可能多的事件,只要我们需要。

例如:

document.body.addEventListener("mousemove",function(){

//为mousemove事件注册处理器

......

});

document.body.addEventListener("click",function(){

//为click事件注册处理器

......

});

事件处理背后的主要思想是:当事件发生时,浏览器调用相应的事件处理器,由于单线程执行模型,所以同一时刻只能处理一个事件,任何后面的事件都只能在当前事件处理器完全结束执行后才能被处理

为了响应用户的动作,浏览器把鼠标移动和单击事件以它们发生的次序放入事件队列,第一个是鼠标移动事件,第二个是鼠标单击事件

在事件处理阶段,事件循环会检查队列,其发现了队列的前面有一个鼠标移动事件,然后执行了相应的事件处理器,当鼠标移动事件处理完后,轮到了等待在队列中的鼠标单击事件,一旦单击处理器执行完成,队列中不再有新的事件,事件循环就会继续循环,等待处理新到来的事件,这个循环会一直执行到用户关闭了web应用