2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > JavaScript事件学习之事件流 处理程序和对象总结

JavaScript事件学习之事件流 处理程序和对象总结

时间:2019-11-18 04:45:20

相关推荐

JavaScript事件学习之事件流 处理程序和对象总结

web前端|js教程

JavaScript,js,程序

web前端-js教程

asp通讯录源码,vscode文件夹右侧有红点,ubuntu 打开zip,dos怎么找tomcat位置,sqlite好用不,网页设计软件 adobe,云服务器放置,鼠标经过放大图片效果插件,repeat前端框架指令,爬虫猎人l,php 解压缩,台州seo优化公司,springboot往前端传值,在线考试网站源码下载,html css网页练习素材,淘宝放大镜模板,织梦后台原始密码,html网页页面模板代码下载,java ee学生成绩管理系统,java界面聊天程序lzw

JS与HTML之间的交互通过事件实现。事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。可以使用监听器(或处理程序)来预定事件,以便事件发生时执行相应的代码。这种在传统软件工程中被称为观察员模式,支持页面的行为与页面的外观之间的松散耦合。本文将介绍JS事件相关的基础知识。

A、事件流

事件流描述的是从页面中接受事件的顺序。

事件冒泡

事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的结点(文档)。以下面HTML页面为例,如果你点击了页面中的按钮,那么”click”事件会按照

事件捕获

与事件冒泡的思路相反,事件捕获的思想是不太具体的节点应该更早地接收到事件,最具体的结点应该最后才接收事件。同样还是上面那个例子,点击页面中的按钮之后,”click”事件会按照document、、、function handler() { alert("Haha~"); }

DOM0级事件处理程序

通过JS指定事件处理程序的传统方式就是将一个函数赋值给一个事件处理程序属性,请看下面代码示例。通过这种方式指定的事件处理程序是在元素的作用域中运行,this引用的是当前元素。这种方式添加的事件处理程序会在事件流的冒泡阶段被处理。若要删除事件,直接令onclick的值为空即可。

var btn = document.getElementById("myBtn");btn.onclick = function() { console.log("this.id"); // "myBtn"};// 删除事件处理程序btn.onclick = null;

DOM2级事件处理程序

“DOM2级事件”定义了两个方法用于指定和删除事件处理程序,addEventListener()和removeEventListener()。所有DOM节点中都包含这两个方法。这两个方法都接收3个参数,要处理的事件、处理函数、布尔值。最后的布尔值为true时表示在捕获阶段调用事件处理程序,为false时表示在冒泡阶段调用处理程序。与DOM0级方法一样,这里添加的事件处理程序也是在其依附的元素的作用域中运行。DOM2级方法添加事件处理程序的优势是可以添加多个事件处理程序。这些事件处理程序会按照它们被添加的顺序触发。下面是代码示例:

var btn = document.getElementById("myBtn");// 添加,触发点击事件时先输出"myBtn"再输出"HaHa~"btn.addEventListener("click", function() { console.log(this.id);}, false);btn.addEventListener("click", function() { console.log("HaHa~");}, false);

通过addEventListener()添加的事件只能通过removeEventListener()来删除。删除时传入的参数与添加时使用的参数应该保持一致。这也意味着通过addEventListener()添加的匿名函数将无法删除,因为无法将添加时传递的匿名函数传给removeEventListener(),即便在删除的时候写了一个一模一样的函数,但此时这个函数只是一个新的匿名函数。请看下面代码示例:

var btn = document.getElementById("myBtn");// 无法删除匿名函数btn.addEventListener("click", function() { console.log(this.id);}, false);btn.removeEventListener("click", function() { console.log(this.id);}, false); // 正确的添加和删除方式function handler() { console.log(this.id);}btn.addEventListener("click", handler, false);btn.removeEventListener("click", handler, false);

大多数情况下,都是将事件处理程序添加到事件流的冒泡阶段,这样可以最大限度地兼容各种浏览器。最好只在需要在事件到达目标之前截获它的时候才将事件处理程序添加到捕获阶段。JS高级程序设计上给出的建议是,如果不是特别需要,不建议在事件捕获阶段注册事件处理程序。

IE事件处理程序

IE实现了与DOM中类似的两个方法: attachEvent()和deleteEvent()。这两个方法接收两个参数,事件处理程序名称和事件处理程序。注意,第一个参数是事件处理程序名称而不是事件名称,也就是说在注册点击事件的处理程序时应该传入”onclick”而不是”click”,这里跟DOM的方法有些差别。另外,这两个方法注册的事件处理程序是在全局作用域中运行而不是元素作用域,this的值指向window。还有一点需要特别小心,通过attachEvent()方法也可以添加多个事件处理程序,但是它们的执行顺序却不是按照它们被添加的顺序,而是完全相反,跟DOM方法截然不同。突然觉得IE真的特别反人类~~~下面是代码示例:

var btn = document.getElementById("myBtn");function handler1() { // ... }function handler2() { // ... }// 添加,触发点击事件时先执行handler2再执行handler1btn.attachEvent("onclick", handler1);btn.attachEvent("onclick", handler2);// 删除btn.deleteEvent("onclick", handler1);btn.deleteEvent("onclick", handler2);

C、事件对象

在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息,包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。

DOM中的事件对象

兼容DOM的浏览器会将一个event对象传入事件处理程序中,无论指定事件处理程序时用的是DOM0还是DOM2的方法,都会传入event对象。event对象只有在事件处理程序执行期间才会存在,一旦事件处理程序执行完毕,event对象就会被销毁。下面是代码示例:

var btn = document.getElementById("myBtn");btn.onclick = function(event) { console.log(event.type); // "click"}btn.addEventListener("click", function(event) { console.log(event.type);}, false);

event对象包含与创建它的特定事件有关的属性和方法,触发的事件类型不一样,可用的属性方法也有所不同。但是所有的事件都会有下列的属性或方法:

bubbles: 布尔值,表示事件是否冒泡

cancelable: 布尔值,表示是否可以取消事件的默认行为

currentTarget: 元素,事件处理程序当前正在处理事件的那个元素

defaultPrevented: 布尔值,表示是否调用过preventDefault()方法

detail: 整数,与事件相关的细节信息

eventPhase: 整数,调用事件处理程序的阶段,1表示捕获阶段,2表示目标阶段,3表示冒泡阶段

preventDefault(): 函数,取消事件的默认行为,cancelable为true时可以调用该方法

stopImmediatePropagation(): 函数,取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用

stopPropagation(): 函数,取消事件的进一步捕获或冒泡,bubbles为true时可以调用这个方法

target: 元素,事件的目标

trusted: 布尔值,为true时表示事件是浏览器生成的,否则表示事件是通过JS创建的

type: 字符串,被触发的事件类型

view: 与事件关联的抽象视图,等同于发生事件的window对象

下面代码示例展示了上述部分属性的用法,也可以帮助我们进一步理解事件流。假设页面中有一个按钮”myBtn”。当点击按钮时,this和currentTarget都等于body元素,因为事件处理程序是注册在body元素上。target的值却等于按钮元素,因为它是click事件的真正目标。由于按钮上没有注册事件处理程序,结果”click”事件冒泡到了document.body那里才得到处理。

document.body.onclick = function(event) { console.log(event.currentTarget === document.body); // true console.log(this === document.body); // true console.log(event.target === document.getElementById("myBtn")); // true};

再看一个例子,下面代码中,stopPropagation()方法取消了事件的进一步捕获或冒泡。当我点击按钮时,本来应该会因为事件冒泡机制触发按钮和body元素上的点击事件处理程序,输出”From Bth …”和”From Body …”。现在点击事件在按钮元素上触发之后就被阻止继续在DOM层次中的传播,因此body上的事件处理程序不会被触发。

var btn = document.getElementById("myBtn");btn.onclick = function(event) { console.log("From Bth ..."); event.stopPropagation(); // 停止事件传播};document.body.onclick = function() { console.log("From Body ...");};

IE中的事件对象

在IE中,使用DOM0的方法添加事件处理程序时,event对象作为window对象的一个属性存在。如果是通过attachEvent()方法添加,则event对象是作为参数传入事件处理函数。下面是代码示例:

var btn = document.getElementById("myBtn");btn.onclick = function() { var event = window.event; console.log(event.type); // "click"};btn.attachEvent("onclick", function(event) { console.log(event.type); // "click"});

IE的event对象同样也包含与创建它的事件相关的属性和方法,这些属性和方法也会因为事件类型的不同而有所差异。但所有事件对象都会包含下列属性:

cancelBubble: 布尔值,可读可写,默认为false。将其设置为true时取消事件冒泡

returnValue: 布尔值,可读可写,默认为true。将其设置为false时取消事件的默认行为

srcElment: 元素,事件的目标元素,与DOM中的target属性相同

type: 字符串,事件类型

在IE中,事件处理程序的作用域是根据指定它的方式来确定,this的值不一定是指向事件的目标元素。因此,使用srcElement属性更具保险。请看下面代码实例,第一种方式中this的值为目标元素,而第二种方式,前面讲过这种方式的事件处理程序是在全局作用域中执行,因此this的值为window。

var btn = document.getElementById("myBtn");btn.onclick = function() { console.log(window.event.srcElement === this); // true}btn.attachEvent("onclick", function(event) { console.log(event.srcElement === this); // false});

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。