✍️ Tangxt | ⏳ 2020-06-25 | 🏷️ DOM 事件 |
我们知道 DOM 有这样一些知识:
以上这些知识都是 DOM 的基础知识,它们大部分无外乎就是一些常用方法,以及相关方法和相关属性的应用而已
以上这些知识的学习:
会讲什么?
而这些东西,就属于「DOM 事件」里边的内容!
总之:
围绕 DOM 事件,以及事件的传播机制、事件池相关机制、一些经典思想,如事件代理和事件委托等,再如发布订阅设计模式,还有在常规案例中,我们如何利用 DOM 事件去做一些相关处理
事件是浏览器天生就具备的行为,无论我们是否基于 JS 代码绑定相关方法,只要相关的行为触发了,那么则一定会触发相关的事件!
事件是 V8 引擎封装好的……我们只是通过一些 DOM 接口,拿到了用户的行为,反馈给了我们的事件处理函数……
类 或对象可以通过事件向其他类或对象通知发生的相关事情。 发送(或引发)事件的类称为“发布者”,接收(或处理)事件的类称为“订阅者”。
话说,我的鼠标指针移入上图里边这个「绿色小块」会有哪些行为被触发了呢?
mouseover 鼠标经过
mouseout 鼠标离开
mouseenter 鼠标进入
mouseleave 鼠标离开
mousemove 鼠标移动
mousedown 鼠标按下
mouseup 鼠标抬起
click 单击(点几次触发几次)
dblclick 双击(在 300ms 内连续触发两次点击,则认为是一次双击)
mousewheel 鼠标滚轮滚动
contextmenu 鼠标右键点击
……
[dbl]click
指的是鼠标左键点击,可不是右键点击哈!关于
click
:当用户的焦点在按钮上并按了Enter
键时,同样会触发这个事件
只要我们对页面里边的某个元素用鼠标发生了以上行为,那么就会触发事件,虽然我们看不到肉眼可见的效果,但是它确确实实就是发生了
keydown 按键按下
keyup 按键抬起
keypress 按键长按
input 文本框内容输入中(改变中)
……
change 内容改变,下拉菜单改变
blur 文本框失去焦点
focus 文本框获取焦点
scroll 滚动条滚动事件
submit 表单提交中的提交事件
resize 大小改变
load 加载(加载完成)事件
error 加载失败事件
DOMContentLoaded DOM 结构加载完成
drag/dragstart/dragend…… H5 中新增的拖拽的相关事件
……
[touch 单手指操作模型]
touchstart 手指按下
touchmove 手指移动
touchend 手指离开
touchcancel 因为意外情况导致操作结束
[gesture(手势)多手指操作模型]
gesturestart/gestureend/gesturechange……
HTMLElement.click()
方法,或者定义事件,然后使用 EventTarget.dispatchEvent()
将其发送到指定的目标。Q:`box.onclick = function(){}`的读法?
常见的错误读法:
给盒子绑定个点击事件
box
它天生自带 click
事件,需要你去绑么?
正确的读法是:
给盒子的点击事件行为绑定方法
概念:
事件绑定:给元素的某个事件行为绑定方法,这样事件行为触发的时候,对应绑定的方法就会执行,完成一些需要完成的功能!
事件绑定可不是为元素绑定事件呀!而是绑定方法呀!
事件绑定可分为:
ele.onxxx = function(){}
ele.addEventListener('eventType',function(){},false)
ele.attachEvent('onxxx',function(){})
-> 基本不用话说,为啥没有 DOM1 级 事件绑定呢?
因为 API 没啥变化,而 DOM2 级的事件绑定 API 发生了巨大的变化!
反正,升级过程,就是 API 的变化过程……
DOM0 级可以认为
onclick
是btn
的一个属性,DOM2 级则将属性升级为队列
事件绑定的原理就是给当前元素对象的某些私有属性(隶属于事件的属性,形式如
onxxx
)赋值为一个函数,当事件行为触发,浏览器就会帮助把绑定的方法给执行了……
如:
// 事件绑定
box.onclick = function () {}
// 移除事件绑定
box.onclick = null
特点:
ontransitionend
/onDOMContentLoaded
……)则无法给这些事件绑定方法 -> 你天生不具备这些属性,意味着你不需要这些事件绑定……(你自己手动写上去是无效的,浏览器可不会傻傻的去执行这些手动绑定的方法)EventTarget.prototype
,使用内置的 addEventListener
或者 removeEventListener
进行事件绑定和移除事件绑定box.addEventListener('ontransitionend',callback)
)注意:
DOM2 事件绑定的时候,我们一般不绑定匿名方法(以方便后期的移除) -> 毕竟移除的时候需要根据事件和方法去移除
代码:
第三个参数,默认是
false
这给我的感觉是:
onclick
、addEventListener('click')
,谁先执行,那么 click
事件绑定的方法就谁先执行addEventListener('click')
重复绑定一个方法,那么是会剔除的,相当于是数组去重一样DOM0 VS DOM2 性能:
DOM0 要好那么一丢丢,可忽略不计,总体上来说 DOM2 要强大多!
也会记录传播模式,在这里先不涉及先!
在真实开发过程中,DOM0 和 DOM2 是可以共存的,它们不会冲突,因为它们用的机制是不一样的 -> 一般来说,以用 DOM2 偏多一些,因为其机制相对比较完善,而且类似于 JQ 这种类库或者一些常用的插件,基本上也是基于 DOM2 事件绑定封装事件处理方法的
如 JQ 中事件绑定的方法:on/off
-> 最底层也是基于 DOM2 完成的 -> 而bind/unbind/delgate/click/mouseover……
最后都是基于 on/off
完成的
window.onload
和document.ready
(指的是 JQ:$(document).ready
)的区别?
分三个点来说:
window.onload
是等待所有资源都加载完成才会触发执行,而我之前研究过部分 JQ 源码,发现$(document).ready()
底层用的是DOMContentLoaded
事件,而该事件本身是 DOM 结构加载完成就会触发执行,所以$(document).ready()
要优先于window.onload
触发window.onload
是基于 DOM0 事件绑定的,所以它只能绑定一个方法,即在页面里边,即一次事件的触发,只能执行一个绑定的方法;而 JQ 中的事件绑定都是基于 DOM2 完成的,所以可以在同一个页面里边绑定多个不同的方法,说白了,一次事件触发,可以执行很多个不同的callback
。我之前在使用 JQ 的开发里边,经常把编写好的模块代码放到$(function(){})
(实质是$(document).ready()
)这里,而这样做既能形成闭包,又能保证 DOM 结构加载完才会执行callback
一定能够获取到 DOM 元素,以防把 JS 放到 DOM 之前加载,导致元素无法获取的问题(引申出来的问题:JS/CSS/IMG/结构加载的顺序和机制 -> 浏览器渲染机制)➹:JavaScript 和 DOM 的产生与发展 - IT 笔录
➹:理解:javascript 中 DOM0,DOM2,DOM3 级事件模型 - 掘金
➹:DOM 事件模型(DOM0,1,2 Event Model) - 知乎
➹:onclick 与 addEventListener 区别 - 知乎
名词:
在计算机里边,我们要与计算机通信,需要用到硬件设备或程序,而用到的这些东西就是「接口」
我们的鼠标要与浏览器通信,就得通过 Event Interface 来搞!
其它的含义: