js的三大事件、事件移除、事件循环机制

什么是事件,三种事件模型

事件是用户操作网页时发生的交互动作或者网页本身的一些操作。
现代浏览器一共有三种事件模型:

  • DOM0 级事件模型,这种模型不会传播,所以没有事件流的概念,但是现在有的浏览器支持以冒泡的方式实现,它可以在网页中直接定义监听函数,也可以通过 js 属性来指定监听函数。所有浏览器都兼容这种方式。
    直接在 dom 对象上注册事件名称,就是 DOM0 写法

  • IE 事件模型,在该事件模型中,一次事件共有两个过程,事件处理阶段事件冒泡阶段
    事件处理阶段会首先执行目标元素绑定的监听事件。
    然后是事件冒泡阶段,冒泡指的是事件从目标元素冒泡到document,依次检查经过的节点是否绑定了事件监听函数,如果有则执行。
    attachEvent就是IE事件模型 ,attachEvent用来添加监听函数,可以添加多个监听函数,会按顺序依次执行。

  • DOM2 级事件模型,在该事件模型中,一次事件共有三个过程,
    第一个过程是事件捕获阶段。捕获指的是事件从 document 一直向下传播到目标元素,依次检查经过的节点是否绑定了事件监听函数,如果有则执行。后面两个阶段和 IE 事件模型的两个阶段相同。
    addEventListener 就是DOM2级事件模型

三大事件(鼠标事件、键盘事件、html事件)

1、鼠标事件

  • click:单击
  • dblclick:双击
  • mousemove:鼠标移动
  • mousedown:鼠标按下
  • mouseup:鼠标抬起
  • mouseover:鼠标悬浮
  • mouseout:鼠标离开
  • mouseenter:鼠标进入
  • mouseleave:鼠标离开

2、键盘事件

  • keydown:按键按下
  • keyup:按键抬起
  • keypress:按键按下抬起

3、HTML事件

  • load:文档加载完成
  • select:被选中的时候
  • change:内容被改变
  • focus:得到光标
  • blur:失去光标
  • resize:窗口尺寸变化
  • scroll:滚动条移动

事件委托机制

事件委托指的是,不在事件的发生地设立监听函数,而是在事件发生地的父元素或者祖先元素设置监听器函数,这样可以大大提高性能,因为可以减少绑定事件的元素,比如:

<ul>
  <li></li>
  <li></li>
  <li></li>
</ul>

你要给li元素绑定click事件,
使用事件委托机制的话,就只需要给ul绑定click事件就行了,
这样就不需要给每个li’绑定click事件,减小内存占用,提高效率。

事件的移除

事件的注册方式对应其移除方式
1、 el.onclick = null

var el = document.getElementById("btn");
//事件注册
 el.onclick = function(event){  
     alert(id); 
     el.onclick = null;   //事件删除
 }

2、el.removeEventListener(type,fn,false); //这里 fn 必须是原有绑定的函数,否侧解除无效

var div = document.getElemetById('id');
div.addEventListener('click',test,false);
function test(){
 console.log('remove click');
}
div.removeEventListener('click',test,false);

事件循环机制

0、背景 (重点!!!!

JavaScript 在设计之初便是单线程,即指程序运行时,只有一个线程存在,同一时间只能做一件事

为了解决单线程运行阻塞问题,JavaScript用到了计算机系统的一种运行机制,这种机制就叫做事件循环(Event Loop)

重点!!!!

既然JS是单线程的,那么诸如onclick回调,setTimeout,Ajax这些异步都是怎么实现的呢?

是因为js在浏览器中执行,而浏览器或node是多线程的,为了解决js单线程运行阻塞问题浏览器搞了几个异步线程去辅助JS主线程的运行

浏览器有很多线程,例如:
1、GUI 渲染线程
2、JS 引擎线程
3、定时器触发线程 (setTimeout)
4、浏览器事件线程 (onclick)
5、http 异步线程
6、EventLoop轮询处理线程
......

那么主线程与这些异步线程之间的运行机制,就是事件循环机制

为什么要把js设计成单线程 ?
因为JavaScript 初期作为一门浏览器脚本语言,通常用于操作 DOM ,如果是多线程,一个线程进行了删除 DOM ,另一个添加 DOM,此时浏览器该如何处理?

JS为什么会有事件循环机制

JavaScript 有事件循环机制,这是因为它是一种单线程语言,也就是说,JavaScript 引擎在同一时间只能执行一个任务。 但是如果 JavaScript 要处理耗时的操作(比如请求远程数据、读取文件等),会造成阻塞,导致用户界面无响应。

1、是什么

前言:
JavaScript 有一个主线程和调用栈,所有的任务最终都会被放到调用栈等待主线程执行。

主线程之外存在一个任务队列,任务队列中就是异步任务的回调,最终这些回调会被调用栈读取后放入主线程中运行。

Event Loop 具体过程如下:

1.1, js在执行代码时,由上至下进行解析;

1.2, 首先,遇到任务,判断该任务是同步还是异步任务;

1.3, 同步任务会被放在调用栈中,按照顺序等待主线程依次执行。

1.4, 如果是异步任务开启异步线程,执行异步任务( 而主线程继续执行同步代码 )
异步任务 执行完后,将其回调函数 放入相应的任务队列(Event Queue)中,而任务队列分为宏任务队列与微任务队列,等待任务的执行。

1.5,调用栈内的任务执行完毕时,此时主线程处于空闲状态,会去 任务队列 读取任务,再把它推入主线程执行。(读取任务队列中的任务时,优先读取微任务,后读取宏任务),执行完一个再去 任务队列读取异步任务,把任务放到主线程中执行,如此循环,这就是 JavaScript 的运行机制,称为 事件循环机制(Event Loop)

总结 js执行顺序: 同步函数 ===》微任务 ===》 宏任务

总结:事件循环机制如下:
1、同步代码,直接执行
2、 异步代码,开启异步线程,执行异步代码,执行完毕后,将其回调函数,放入任务队列中。
3、待同步函数执行完毕,轮询执行任务队列的函数

2、异步任务有哪些,用浏览器的哪个异步线程执行
  • 1、定时任务:setTimeout、setInterval --------- 浏览器定时器线程
  • 2、网络请求:ajax请求、动态img加载 --------- 浏览器http异步线程
  • 3、DOM绑定的事件:dom事件 --------- 浏览器事件线程
  • 4、ES6中的promise.then中的函数

Promise 构造函数是同步执行的,promise.then 中的函数是异步执行的。

3、异步线程何时被放入任务队列?
  • 1、DOM绑定的事件-------- 由浏览器事件线程处理,事件触发时,回调函数添加到任务队列中;
  • 2、定时任务:---------由浏览器定时器线程处理,时间到达时,回调函数添加到任务队列中;
  • 3、网络请求 ----------- 由浏览器http异步线程处理,网络请求返回后,回调函数添加到任务队列中。

ajax加载完成,即ajax什么时候success,就什么时候把ajax中的函数放入到异步队列中

异步任务又分为 宏观任务 、微观任务

4、 异步任务分类: 宏观任务、微观任务
  • 宏观任务包含以下几类
    定时器----setTimeout、setInterval、
    DOM绑定的事件、
    异步Ajax请求
    文件操作

  • 微观任务包含以下几类—常用的ES6新增的方法
    Promise.then、
    async/await (实际上是promise+generator的语法糖)
    Generator

【参考链接】:https://www.cnblogs.com/yugege/p/9598265.html
【参考链接】:https://mp.weixin.qq.com/s/9iN7XR1PwXfua8SrabOi5w

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值