本文探讨了Event的冒泡过程和初学者遇到的几个小bugDOM事件概述Event接口是检测DOM中发生的所有事件。早期版本一直在使用。早期的Netscape(后来的Firefox)和IE各自为战,直到W3C称霸江湖,DOM版本一路发展到DOM-0(史前时代),DOM-1(核心内容只有两章)),DOM-2(一个划时代的版本,我们学习的Event就在这个版本,现在的版本也在用),DOM-3,DOM-4(草稿阶段)。通过一个例子唤醒对Event的理解//1,有一个js函数如下functionprint(){console.log(1)}//2,在html按钮中点击触发上面的函数Clickme//问号可以填什么A.print()B.printC.print.call()//在js=中的onclick中触发button.onclick?//问号可以填什么A.print()B.printC.print.call()很明显,第一个问号应该是AC,第二个问号应该是B,第一位在HTM,点击事件应该立即执行代码。肯定选带()的,排在第二位的是JS中,onclick是不需要立即执行的属性。用户点击后,浏览器会再次响应,不需要()。由于onclick等on事件在JS中都是属性,后面的会覆盖前面的,所以在DOM2中引入了一个重要的EventListener,就是一个队列。addEventListener这是一个队列,例1,具有先进先出的特点,为后面的冒泡模型做准备。functionf(){console.log("eventListener不会覆盖")}button2.addEventListener('click',function(){console.log("eventListener不会覆盖1")})button2.addEventListener('click',f)button2.removeEventListener('click',f)button2.addEventListener('click',function(){console.log("eventListenerwillnotcover3")})会打印出什么,答案是eventListener不会覆盖1个eventListener不会覆盖3个,所以既然on可以一个一个的打印出结果,可以用remove来实现一个执行一次的操作functionf(){console.log("eventListenerwillnotcover2")button2.removeEventListener('click',f)}button2.addEventListener('click',f)只会打印一次,不会一直打印,就是一个的原理。具体模型可以参考W3C冒泡模型上面的官方文档。我只研究捕获阶段和冒泡阶段。什么是冒泡?我们先来看一段代码IamyouDad')})son.addEventListener('click',function(){console.log('Iamyourson')})这是三个div的事件,当你点击的时候,console会打印顺序.那么顺序应该是怎样的呢?正常人的思维无非就是两种结果。第一:我是你儿子,我是你爸爸,我是你爷爷。第二个:我是你爷爷,我是你爸爸,我是你儿子。哪一个?W3C说没问题。这取决于你的代码是如何编写的。上面的代码是按第一顺序打印的,也就是冒泡。如果要实现第二种打印方式,即捕获阶段,修改代码如下grand.addEventListener('click',function(){console.log('我是你爷爷')},true)dad.addEventListener('click',function(){console.log('我是你爸爸')},true)son.addEventListener('click',function(){console.log('我是你儿子')},true)也就是说addEventListener后面的参数决定了顺序。不写的时候就是undefined,也就是false。复习五个假值0NaN''nullundefined其他都是真上图是一个简单的说明,注意先为真的部分,再为假的部分。简单示例=====================>演示一个变体grand.addEventListener('click',function(){console.log('Iamyourgrandpa')},true)dad.addEventListener('click',function(){console.log('我是你爸爸')})son.addEventListener('click',function(){console.log('我是你儿子')上面代码的顺序应该是什么?谁为真,谁先打印,全部为假,按照冒泡的顺序继续打印。奇葩问题son.addEventListener('click',function(){console.log('Iamyoursontrue')},true)son.addEventListener('click',function(){console.log('Iamyoursonfalse')})给出相同的元素falsetrue,what应该打印吗?答案是:按照写的顺序,谁先打印。意想不到的bugparent是关键字不能用,一不小心用了就会出问题。你把关键字当成变量,可以'单击鼠标也看不到效果。单击空白处,对话框消失。案主说有需求。单击一个按钮,将弹出一个对话框。单击空白,它将消失。你的第一个想法:先把div设置为none,点击button的时候,让div的显示是一个块,点击其他地方改成none。很好,你去实施吧。第一个错误您很快就会遇到第一个错误。第一个错误:监控到错误的对象。正常情况下,你应该点击机身控制台打印数字1,如果你点击它,你的罗技鼠标就出不来了。为什么?我们用border的方法看它用红色边框的地方,发现body的高度太矮了,无法点击。你明白是听错对象了,那你换个对象听文档,肯定没问题。第二个错误非常好。你进入了第二个错误。第二个BUG:可以点击,但是不能弹出对话框。根据图中的控制台,可以发现已经点进去了,监控是没有问题的,而点击之后,也是按照冒泡的顺序打印出来的结果。那为什么没有对话框呢?注释掉有问题的代码后,上图是正常点击,出现对话框,说明问题出在注释的代码上。bug的原因是:默认冒泡的影响,点击浮层上的div,之后冒泡到body文档,在文档上立马被杀死,显示变为无.你可以在你的dreamsBox中看到弹出窗口。修复第二个bug既然知道了第二个bug的原因,那么我们就可以防止冒泡序列的解决,防止它向上冒泡,自己管理。clickMe.addEventListener('click',function(){popover.style.display='block'console.log('点击浮层')})wrapper.addEventListener('click',function(e){e.stopPropagation()})document.addEventListener('click',function(){popover.style.display='none'console.log('Iclickedonthedocument')})但是接下来是关于内存使用的问题,现在你只有一个popover,只有一个function,当你有很多popovers的时候,按照这个写法就会有很多fun??ctions,所以不能这样写,用下面的写法来节省内存。$(clickMe).on('click',function(){$(popover).show()console.log('show')setTimeout(function(){console.log('oneclick')$(document).one('click',function(){console.log('我认为他不会执行')$(popover).hide()})},0)})//$(wrapper).on('click',function(e){//e.stopPropagation()//})$(document).on('click',function(){console.log('Gotodocument')})只点击它仅在使用时使用。设置settimeout的目的是让它异步,以免马上隐藏起来,产生第一个bug。注意jQuery的show()hide()只会在点击按钮的时候打印图片中的两句话,再次点击才会打印另外两句话。JS版省内存版==================>jQuery版省内存版==================>jQuerysavememorydialog小三角形制作.popover{display:inline-block;边框:1px纯红色;位置:相对;填充:10px;margin:10px;}.popover::before{position:absolute;内容:'';顶部:5px;右:100%;边框:10px实心透明;border-right-color:red;}.popover::after{content:'';边框:10px实心透明;位置:绝对;:100%;顶部:5px;右边框颜色:白色;margin-right:-1px;}主要用到了border-right-color和两个伪元素。浮层三角形示例======================================================================================================================================================================================================================================>demo冒泡的直观体现/github.com/codevvvv9/bubble/blob/master/bubble.gif拿个泡泡