谈谈我对JavaScript DOM事件的理解


Posted in Javascript onDecember 18, 2015

什么是事件?

事件(Event)是JavaScript应用跳动的心脏 ,也是把所有东西粘在一起的胶水。当我们与浏览器中 Web 页面进行某些类型的交互时,事件就发生了。事件可能是用户在某些内容上的点击、鼠标经过某个特定元素或按下键盘上的某些按键。事件还可能是 Web 浏览器中发生的事情,比如说某个 Web 页面加载完成,或者是用户滚动窗口或改变窗口大小。

通过使用 JavaScript ,你可以监听特定事件的发生,并规定让某些事件发生以对这些事件做出响应。

DOM与事件是JavaScript最核心的组成部分之一,他们赋予了页面无限的想象空间,你根本无法离开他们,否则js将寸步难行。在我们平时的开发过程中,jQuery的出现使得我们得心应手,然而你必须知道,jQuery之所以把事情简单化,是得益于JavaScript本身提供的强大的API,你应该去熟悉它们。

首先,此文不讨论繁琐细节,但是考虑到读者的心灵感受,本着以积极向上的心态,在此还是会列举示例说明。

​标题为理解DOM事件,那么在此拿一个简单的点击事件为例,希望大家看到这个例子后能触类旁通。
 最初我们给页面实现点击,就像下面这样的简单操作。

先定义一个块如<div id="weiyuzhou">微宇宙</div>,之后在<script type="text/javascript"></script>内部实现id为weiyuzhou的点击事件,如下代码所示:

var wyz = document.getElementById('weiyuzhou');
wyz.onclick = function () {
confirm(arguments.length)
}

确保上面这些步骤都没问题的话,我们才可以继续的往下走,然后我们在IE浏览器(低版本)看到弹出0,确切的说,IE8以下(包含IE8)的弹出0,反之弹出1。接着我在firefox浏览器看到弹出1。也就是说在IE8以下版本事件的触发不存在于函数的作用域内部,是不是说IE8以下的事件触发发生在全局作用域中,此处留个悬念,但是,可以肯定的是IE8以下事件的方法并没有这个Event参数,也就是说arguments的长度为0,如下视图5-02所示:

5-02

谈谈我对JavaScript DOM事件的理解

于是,我们看firefox浏览器窗口弹出1,说明事件存在于函数内部,再次证明方法的内部数组arguments长度为1,并且是可枚举的变量,也可以说可写,如下视图5-03所示。

5-03

谈谈我对JavaScript DOM事件的理解

如果,你还是不明白其中的原理,你不防去看一下《web前端开发修炼之道》书上第169页,然后再回过头来看此处文章摘要,可能会让你更加深层次的了解书中的内容。

接下来,我们该怎么办呢,我们肯定不能让IE和firefox返回的事件输出不相同,那么如何让IE和firefox下弹出的内容都一样。

衔接上一段内容,下面给点击函数的内部设置一个参数,参数名为e,然后在IE和firefox浏览器下面同时触发点击事件,我们看到firefox下面显示e为鼠标事件[object MouseEvent],IE8下报错,弹出错误信息未定义undefined。此时你要问我错在哪里,咱们回到刚刚的那句话‘此处留个悬念'进行分析,IE8以下的浏览器的事件是不是发生在全局作用域中,从视图5-02所示看到有一个global全局对象,我们可以对global展开搜索,global的继承的方法有一个event事件,找到了IE8的专有事件方法window继承event,于是我们对这个参数e设置为window.event进行一个调试,目前我们在IE8下面看到返回了一个事件[object event],如图5-04所示。

5-04

 谈谈我对JavaScript DOM事件的理解

想必你一定发现了IE8和firefox浏览器下对话框的事件返回值各不不同,IE8的对话框[object MouseEvent],firefox的对话框[object event],那我们怎么让IE8和firefox下的返回值都相同呢?

看到这里,你的心里是不是有点小沮丧,挖坑挖了这么久了,怎么还没有看到水流出来,别急,正题才刚刚开始,咱们不闲聊,继续围绕正题展开分析,通过刚刚的返回值,我们继续使用断点的方法寻找能够实现IE和firefox的返回值的共同点。

经由以上分析,我们查找发现firefox下的event有我们需要的方法名可以被调用,当然,我们查找发现IE8下面的srcElement也有我们所需的方法名可以被调用,于是乎,呵呵!看到这里你的内心是不是有点小激动,一步步排除,最后发现也没有什么难的。回到正题,现在我们声明一个变量var e_child = e.srcElement || e.target; 然后我们在IE8和firefox浏览器上看到对话框信息都为[object HTMLDivElement],如图5-05所示。

5-05

 

谈谈我对JavaScript DOM事件的理解

谈谈我对JavaScript DOM事件的理解

现在我们解决了不同浏览器的返回值不同的问题,也就是说解决了兼容的问题,这只是冰上一角。

下面我们要解决实现窗口的容器触发事件,主要是基于上面的结构进行的一次分析。

当你有了上面基础的话,下面的内容相对于上面而言比较简单一点。

还是以上一个页面的块为例,现在我继续往块<div id="weiyuzhou">微宇宙</div>增加一个子容器,这个子容器为行内元素<span id='coz'>koringz</span>,取id名为coz,然后给这个元素也加一个点击事件代码同上函数,为了能区别开文本内容之间的差异。

当我分别在IE8和firefox下点击容器的内容,出现了怪异的情况,在firefox浏览器的窗口上点击时,点击中文文本内容弹出来对话框‘微宇宙',我再点击koringz时,发现弹出了二次对话框,弹出内容都为'koringz',那是因为我点击子容器的时候触发了上一层的点击行为,如何解决点击koringz弹出二次对话框的问题,了解一点js的程序员都知道这是冒泡事件。

那么在firefox能够清除冒泡事件的是event下的stopPropagation,于是我们给第二次点击事件函数代码块之后面加一行代码e.stopPropagation();之后再点击koringz发现弹出一次'koringz'。如图5-06所示

 5-06

 谈谈我对JavaScript DOM事件的理解

接下来在IE8下面测试一下,发现在IE8浏览器点击也弹出二次,解决IE8的停止冒泡事件为cacelBubble,且我们只需要给cacelBubble设置为true即可。

因为IE8下global包含的event属性cacelBubble不是一个方法,而是一个输出布尔值的对象,所以这个和firefox有所不同,只是firefox把此事件封装成方法而已。好了,现在我们给第二次点击的事件代码块之后再加一行代码e.cancelBubble = true;然后在IE8浏览器下测试,之后再点击koringz发现也弹出一次。如图5-07所示

5-07

 谈谈我对JavaScript DOM事件的理解

注意上面的停止冒泡的事件的代码可以根据浏览器的不同分开来写,如何分开写,我们查看IE8浏览器下面的document发现存在对象all,而在firefox却没有没有这个all属性,这也就是说document.all是IE8版本下面独有的一个属性。通过它我们可以区分浏览器的冒泡事件。

到目前为止,我们解决了窗口的冒泡事件,接下来,我们要解决一个事件因被多人定义而覆盖原函数的问题。也可能是说某公司之前的工作人员添加了此事件,后来新员工接手项目后添加修改此事件而覆盖了原事件的执行所产生的问题。也就是说给当前id多次添加此类事件都不会覆盖此事件的原函数执行。

在firefox下的window包含有addEventListener(type, listener, useCapture)的方法,随后我们在<script type="text/javascript"></script>内部定义此监听事件domElement.addEventListener('click',function(e){confirm(e+'e')},false);,接着在firefox浏览器点击内容弹出二次,最后一次弹出为[object MouseEvent]e,后面多了一个e,这是我有意加上用以区别的。如图5-08所示。

5-08

 谈谈我对JavaScript DOM事件的理解

接下来在IE8下测试发现addEventListener错误,但是看到window下有此类方法(尝试了一下,原来此类方法在IE9以上版本是可以被支持),IE8同时还有一个attachEvent(event, pdisp),那么我们设置监听事件wyz.attachEvent('onclick',function(e){confirm(e + 'e')}),注:event为'onclick',紧接着在IE8下点击发现可弹出二次,最后一次eIE。此时on('click',pdisp)和attachEvent(event,pdisp)可以共同使用。

综上所述,我们解决了DOM事件的兼容性,DOM事件的冒泡,以及DOM事件的重用。

Javascript 相关文章推荐
解决FLASH需要点击激活的代码
Dec 20 Javascript
JavaScript EasyPager 分页函数
May 25 Javascript
Javascript绝句欣赏 一些经典的js代码
Feb 22 Javascript
jquery解析xml字符串简单示例
Apr 11 Javascript
JavaScript实现穷举排列(permutation)算法谜题解答
Dec 29 Javascript
JavaScript实现动画打开半透明提示层的方法
Apr 21 Javascript
javascript获取wx.config内部字段解决微信分享
Mar 09 Javascript
简单理解js的prototype属性及使用
Dec 07 Javascript
JavaScript中闭包的详解
Apr 01 Javascript
React简单介绍
May 24 Javascript
Vue2.0 slot分发内容与props验证的方法
Dec 12 Javascript
vue+springboot+element+vue-resource实现文件上传教程
Oct 21 Javascript
JavaScript中字符串与Unicode编码互相转换的实现方法
Dec 18 #Javascript
jQuery Validation PlugIn的使用方法详解
Dec 18 #Javascript
最简单的JavaScript图片轮播代码(两种方法)
Dec 18 #Javascript
JS弹出对话框实现方法(三种方式)
Dec 18 #Javascript
jQuery Validate表单验证深入学习
Dec 18 #Javascript
JavaScript计划任务后台运行的方法
Dec 18 #Javascript
JavaScript jQuery 中定义数组与操作及jquery数组操作
Dec 18 #Javascript
You might like
php模拟ping命令(php exec函数的使用方法)
2013/10/25 PHP
PHP自带函数给数字或字符串自动补齐位数
2014/07/29 PHP
从零开始学YII2框架(一)通过Composer安装Yii2框架
2014/08/20 PHP
php基础设计模式大全(注册树模式、工厂模式、单列模式)
2015/08/31 PHP
php实现的递归提成方案实例
2015/11/14 PHP
Microsoft Ajax Minifier 压缩javascript的方法
2010/03/05 Javascript
在VS2008中使用jQuery智能感应的方法
2010/12/30 Javascript
javascript 主动派发事件总结
2011/08/09 Javascript
使用apply方法处理数组的三个技巧[译]
2012/09/20 Javascript
js实现点击链接后窗口缩小并居中的方法
2015/03/02 Javascript
jquery实现可自动判断位置的弹出层效果代码
2015/10/12 Javascript
AngularJS入门教程之模块化操作用法示例
2016/11/02 Javascript
javascript阻止事件冒泡和浏览器的默认行为
2017/01/21 Javascript
JS数组去重(4种方法)
2017/03/27 Javascript
Angular实现双向折叠列表组件的示例代码
2017/11/21 Javascript
layui prompt 设置允许空白提交的方法
2019/09/24 Javascript
vue封装swiper代码实例解析
2019/10/08 Javascript
前端vue-cli项目中使用img图片和background背景图的几种方法
2019/11/13 Javascript
原生javascript实现类似vue的数据绑定功能示例【观察者模式】
2020/02/24 Javascript
[06:44]2014DOTA2国际邀请赛-钥匙体育馆开战 开幕式振奋人心
2014/07/19 DOTA
[46:20]CHAOS vs Alliacne 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
Python 网络爬虫--关于简单的模拟登录实例讲解
2018/06/01 Python
Python帮你识破双11的套路
2019/11/11 Python
Windows 平台做 Python 开发的最佳组合(推荐)
2020/07/27 Python
Python调用系统命令os.system()和os.popen()的实现
2020/12/31 Python
Shopee马来西亚:随拍即卖,最佳行动电商拍卖平台
2017/06/05 全球购物
高分子材料与工程专业个人求职信
2013/12/15 职场文书
作弊检讨书1000字
2014/02/01 职场文书
法律顾问服务方案
2014/05/15 职场文书
幼儿园大班个人总结
2015/02/28 职场文书
自我推荐信怎么写
2015/03/24 职场文书
英文投诉信格式
2015/07/03 职场文书
公司员工管理制度
2015/08/04 职场文书
python如何获取网络数据
2021/04/11 Python
python中__slots__节约内存的具体做法
2021/07/04 Python
python机器学习实现oneR算法(以鸢尾data为例)
2022/03/03 Python