基本概念
事件就是文档或浏览器窗口中发生的一些特定的交互瞬间
DOM事件的级别,准确的说,是DOM标准定义的级别,分为以下几个:
DOM0:element.onClick=function(){}
// 只能绑定一个事件处理函数,如果绑定了多个事件处理,取最后一个
// 事件冒泡机制
DOM2:element.addEventListener('click',function(){},false)
// 可以绑定多个事件处理函数
// 添加了事件捕获机制
// 最后一个参数false代表事件在冒泡阶段执行,true代表事件在捕获阶段执行
DOM3:element.addEventListener('keyup',function(){},false)
// DOM3相对于DOM2,事件类型增加了许多,比如鼠标事件,键盘事件等。
好奇:为什么么有DOM1呢?这是因为DOM1标准制定的时候,没有设计跟事件相关的东西,所以在说DOM事件级别的时候,直接就跳过DOM1。但是DOM1标准是存在的。
事件模型
事件模型分为捕获和冒泡两个过程
事件流
浏览器为当前页面与用户做交互(比如点击鼠标左键)的过程中,这个交互(鼠标左键点击)是怎么传到页面上,就是事件流。
事件流分为三个阶段,捕获 => 目标阶段 => 冒泡
- 第一阶段是捕获
- 第二阶段是目标阶段
事件通过捕获到达目标元素(比如点击某一个按钮),就是目标阶段。 - 第三阶段是冒泡
事件从目标元素上传到window对象,就是冒泡。
描述DOM事件捕获的具体流程
window => document => html => body => ... => 目标元素
【知识点】
取得body标签的方法:document.body
取得html标签的方法:document.documentElement
Event对象的常见应用
-
event.preventDefault()
概念:阻止浏览器默认事件
举例:比如对一个a标签的点击事件设置event.preventDefault(),就会阻止跳转行为。 -
event.stopPropagation()
概念:该方法作用在后续节点上,目的在执行完绑定到当前元素上的所有事件处理程序之后,停止执行所有后续节点的事件处理程序,也就是阻止冒泡。
举例:比如子元素绑定了一个点击事件,父元素也绑定了一个点击事件。我们想要点击子元素的时候做一件事,点击父元素的时候做另外一件事。如果不做阻止冒泡,在点击子元素的时候,父元素也会被响应,这不是想要的结果。 -
event.stopImmediatePropagation()
概念:该方法作用在当前节点以及事件链上的所有后续节点上,执行完当前事件处理程序之后,停止当前节点以及所有后续节点的事件处理程序的运行
举例:比如某个元素绑定了点击事件A和事件B,当点击发生的时候,事件A和事件B都会响应。如果希望事件A响应而事件B不响应,该怎么做呢?这时候只需要在事件A的响应函数中,写上event.stopImmediatePropagation()即可。此方法常用于事件的优先级处理上。 -
event.currentTarget和event.target
event.currentTarget:返回绑定事件的元素
event.target:返回触发事件的元素
用一个例子解释这两个属性会比较清楚。
当点击第一个子元素1的时候,显示的内容是:<li>1</li> 和 UL
当点击第二个子元素2的时候,显示的内容是:<li>2</li> 和 UL
<ul id="ul">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
const ul = document.getElementById('ul');
ul.addEventListener('click',function(event){
console.log(event.target)
console.log(event.currentTarget.nodeName)
});
</script>
自定义事件
- 创建自定义事件:new Event('eventName') / new CustomEvent('custom',{detail:{data}})
- 绑定自定义事件:与绑定其他事件的方法一致
- 触发自定义事件:dom.dispatchEvent(eve);
<button id="button1">按钮1</button>
<script>
var button1 = document.getElementById('button1');
var eve = new Event('custom');
button1.addEventListener('custom',function(){
console.log('我是一个自定义事件');
});
button1.dispatchEvent(eve);
</script>
<script>
var button2 = document.getElementById('button2');
var eve = new CustomEvent('custom',{
detail:{
name:'song'
}
});
button2.addEventListener('custom',function(event){
console.log('我是一个自定义事件:',event.detail.name);
});
button2.dispatchEvent(eve);
</script>
封装一个事件绑定函数
通过fn.call(target, e)
使回调函数中的this指向event.target
,从而达到和addEventListener一样的效果。
a.matches(b)
的意思是判断a字符串中是否包含b字符串,如果包含返回true,反之返回false。
<ul id="ul">
<li id="liFirst">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script type="text/javascript">
function bindEvent(elem, type, selector, fn) {
if (fn == null) {
fn = selector;
selector = null;
}
elem.addEventListener(type, function (e) {
var target;
target = e.target;
if (selector) {
// 代理
if (target.matches(selector)) {
fn.call(target, e);
}
} else {
// 不是代理
fn.call(target, e);
}
});
}
var liFirst = document.getElementById('liFirst');
bindEvent(liFirst, 'click', function (e) {
e.stopPropagation();
console.log(this.innerHTML); // 1
});
var ul = document.getElementById('ul');
bindEvent(ul, 'click', 'li', function (e) {
console.log(this.innerHTML); // 点击哪个,显示哪个
// target: <li>2<li>
// selector: li
});
</script>
鼠标事件
- onload:页面加载事件
- onclick:鼠标点击事件
- onmouseover:鼠标滑过事件
- onmouseout:鼠标离开事件
- onfocus:获得焦点时触发
- onblur:失去焦点时触发
- onchange:域的内容改变时发生
- onsubmit:表单中的确认按钮被点击时发生(加在表单上,而不是按钮上)
- onmousedown:鼠标按钮在元素上按下时触发
- onmousemove:在鼠标指针移动时发生
- onmouseup:在元素上松开鼠标按钮时触发
- onresize:当调整浏览器窗口的大小时触发
- onscroll:拖动滚动条滚动时触发
键盘事件
- onkeydown:在用户按下一个键盘按钮时发生
- onkeypress:在键盘按键被按下并释放一个键时发生
- onkeyup:在键盘按键被松开时发生
知识点:keyCode,就是返回onkeypress / onkeydown / onkeyup事件触发的键的代码
网友评论