Javascript 事件
导读
JS事件可以借助WPF路由事件来理解,因为早期浏览器是IE的天下,微软有很多关于渲染和js相关的专利,而WPF是微软推出的,很明显的使用了浏览器内核的编程设计。
与路由事件相同,JS事件也是一种用于元素树的事件。
文章地址:WPF路由事件
https://blog.csdn.net/qinzheng_chen/article/details/103056425
JS事件流
三个阶段的流程图
捕获阶段
捕获阶段处于事件流的第一阶段,该阶段的主要作用是捕获截取事件。在DOM中,该阶段始于Document,结束于body(当然,在现在的很多高版本浏览器中,该过程结束于目标元素,只不过不执行目标元素而已,这也体现了目标元素具有双重范围)。
目标阶段
目标阶段处于事件流的第二阶段,该阶段的主要作用是执行绑定事件。一般地,该阶段具有双重范围,即捕获阶段的结束,冒泡阶段的开始。
冒泡阶段
冒泡阶段处于事件流的第三阶段,该阶段的主要作用是将目标元素绑定事件执行的结果返回给浏览器,处理不同浏览器之间的差异,主要在该阶段完成。
事件冒泡
什么是事件冒泡
在一个对象上触发某类事件(比如单击onclick事件),如果此对象定义了此事件的处理程序,那么此事件就会调用这个处理程序,如果没有定义此事 件处理程序或者事件返回true,那么这个事件会向这个对象的父级对象传播,从里到外,直至它被处理(父级对象所有同类事件都将被激活),或者它到达了对 象层次的最顶层,即document对象(有些浏览器是window)。
打个比方说:你在地方法院要上诉一件案子,如果地方没有处理此类案件的法院,地方相关部门会帮你继续往上级法院上诉,比如从市级到省级,直至到中央法院,最终使你的案件得以处理。
事件冒泡有什么作用
(1)事件冒泡允许多个操作被集中处理(把事件处理器添加到一个父级元素上,避免把事件处理器添加到多个子级元素上),它还可以让你在对象层的不同级别捕获事件。
(2)让不同的对象同时捕获同一事件,并调用自己的专属处理程序做自己的事情,就像老板一下命令,各自员工做自己岗位上的工作去了。
Example
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
var fatherEle = document.querySelector('.father');
var sonEle = document.querySelector('.son');
var fHandler = function () {
alert('father click');
}
var sHandler = function () {
alert('son click');
}
//捕获阶段
fatherEle.addEventListener('click', fHandler, true);
sonEle.addEventListener('click', sHandler, true);
//冒泡阶段
fatherEle.addEventListener('click', fHandler, false);
sonEle.addEventListener('click', sHandler, false);
</script>
</body>
事件对象
事件对象通常写作event 或者e,event 对象代表事件的状态,比如键盘的按键状态,鼠标的位置,鼠标按钮的状态。事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面
function fTest(e) {
alert('other way');
e = e || window.event;//为了兼容ie8以前的版本
console.log(e);
}
//冒泡阶段
fatherEle.addEventListener('click', fTest, false);
sonEle.addEventListener('click', sHandler, false);
事件对象的常用属性
阻止默认事件(链接不实现跳转或者按钮不提交)
<script>
var aEle = document.querySelector('a');
aEle.addEventListener('click',function(e){
e.preventDefault();//dom 标准写法
e.returnValue();// 低版本ie
return false;//return false 可以阻止默认行为,但是return 后面的代码不执行了,而且仅仅限于传统的注册方式
},false);
</script>
阻止冒泡
e.target 、e.currentTarget 和this的区别
事件对象有一些非常关键的属性我们经常要用到,重点讲述一下其中的区别
Demo
<body>
<div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
<script>
var ulEle = document.querySelector('ul');
function showEventArg(e) {
console.log(e.target);
console.log(this);
console.log(e.currentTarget);
}
ulEle.addEventListener('click', showEventArg, false);
</script>
</body>
- e.target 返回的是触发事件的对象
- this 返回的是绑定事件的对象
- e.target 是点击了那个元素就返回那个元素,this是那个元素绑定了点击事件就返回那个元素
- currentTarget 等同于this
- 如果没有冒泡机制 this 和target一定相同,因为事件无法传递出去,绑定的元素就是触发事件的元素
this 的指向的对象
没有学过后端语言的开发人员对对象的理解可能不是特别深刻,这里插入我的理解供参考。
this 官方解释是当前对象
-
case1:在全局作用域下,或者全局作用域函数中 this 指向window
理解:我们知道全局变量都会变成window 对象的属性,所以,所有的全局变量和全局函数实际写法都是window.xx 因此,这种情况下,this 指向window
需要特别注意定时器(window.setTimeout等)this 也指向window -
case2: 对象的方法中 谁调用this 就指向谁
var o = {
sayHi:function (){
console.log(this);
}
}
o.sayHi();
- case3 构造函数中的this 指向构造函数返回的实例。类的构造函数都是为了创建类的对象,this 就是指向这个新创建的对象的
总结&注意
- onclick 和 attachEvent 只能支持冒泡阶段
- addEventListener第三个参数如果是true ,表示在事件捕获阶段调用;如果是false(默认值是false),表示是冒泡阶段
- 在实际开发中,我们很少使用事件捕获,我们更关注事件冒泡
- 有些事件没有冒泡,比如onblur,onfocus,onmouseenter,onmouseleave
转载:https://blog.csdn.net/qinzheng_chen/article/details/115833458