这里有新鲜出炉的 Javascript 教程,程序狗速度看过来!
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
DOM 与事件是 JavaScript 最核心的组成部分之一,他们赋予了页面无限的想象空间,你根本无法离开他们,否则 js 将寸步难行。本文给大家分享我对 javascript dom 事件的了解,对 javascript dom 事件相关知识感兴趣的朋友一起学习吧
什么是事件?
事件 (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
于是,我们看 firefox 浏览器窗口弹出 1,说明事件存在于函数内部,再次证明方法的内部数组 arguments 长度为 1,并且是可枚举的变量,也可以说可写,如下视图 5-03 所示。
5-03
如果,你还是不明白其中的原理,你不防去看一下《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
想必你一定发现了 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
现在我们解决了不同浏览器的返回值不同的问题,也就是说解决了兼容的问题,这只是冰上一角。
下面我们要解决实现窗口的容器触发事件,主要是基于上面的结构进行的一次分析。
当你有了上面基础的话,下面的内容相对于上面而言比较简单一点。
还是以上一个页面的块为例,现在我继续往块微宇宙增加一个子容器,这个子容器为行内元素 koringz,取 id 名为 coz,然后给这个元素也加一个点击事件代码同上函数,为了能区别开文本内容之间的差异。
当我分别在 IE8 和 firefox 下点击容器的内容,出现了怪异的情况,在 firefox 浏览器的窗口上点击时,点击中文文本内容弹出来对话框'微宇宙',我再点击 koringz 时,发现弹出了二次对话框,弹出内容都为'koringz',那是因为我点击子容器的时候触发了上一层的点击行为,如何解决点击 koringz 弹出二次对话框的问题,了解一点 js 的程序员都知道这是冒泡事件。
那么在 firefox 能够清除冒泡事件的是 event 下的 stopPropagation,于是我们给第二次点击事件函数代码块之后面加一行代码 e.stopPropagation(); 之后再点击 koringz 发现弹出一次'koringz'。如图 5-06 所示
5-06
接下来在 IE8 下面测试一下,发现在 IE8 浏览器点击也弹出二次,解决 IE8 的停止冒泡事件为 cacelBubble,且我们只需要给 cacelBubble 设置为 true 即可。
因为 IE8 下 global 包含的 event 属性 cacelBubble 不是一个方法,而是一个输出布尔值的对象,所以这个和 firefox 有所不同,只是 firefox 把此事件封装成方法而已。好了,现在我们给第二次点击的事件代码块之后再加一行代码 e.cancelBubble = true; 然后在 IE8 浏览器下测试,之后再点击 koringz 发现也弹出一次。如图 5-07 所示
5-07
注意上面的停止冒泡的事件的代码可以根据浏览器的不同分开来写,如何分开写,我们查看 IE8 浏览器下面的 document 发现存在对象 all,而在 firefox 却没有没有这个 all 属性,这也就是说 document.all 是 IE8 版本下面独有的一个属性。通过它我们可以区分浏览器的冒泡事件。
到目前为止,我们解决了窗口的冒泡事件,接下来,我们要解决一个事件因被多人定义而覆盖原函数的问题。也可能是说某公司之前的工作人员添加了此事件,后来新员工接手项目后添加修改此事件而覆盖了原事件的执行所产生的问题。也就是说给当前 id 多次添加此类事件都不会覆盖此事件的原函数执行。
在 firefox 下的 window 包含有 addEventListener(type, listener, useCapture) 的方法,随后我们在内部定义此监听事件 domElement.addEventListener('click',function(e){confirm(e+'e')},false);,接着在 firefox 浏览器点击内容弹出二次,最后一次弹出为 [object MouseEvent]e,后面多了一个 e,这是我有意加上用以区别的。如图 5-08 所示。
5-08
接下来在 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 事件的重用。
来源: http://www.phperz.com/article/17/0413/268029.html