该事件继续执行监督机制
●那时来聊聊聊该事件的继续执行监督机制
●甚么是该事件的继续执行监督机制呢?
○思索三个难题?
○当三个大箱子冗余三个小箱子的这时候,因此三个箱子都有点选该事件
○你点选里头的小箱子,外边的大箱子上的点选该事件要千万别继续执行事件的散播(该事件流)
●发展史:
○JS该事件流最先要从IE和Netscape公司的应用程序混战讲起,IE明确提出的是altered流,而Netscape明确提出的是捕捉流,而后在W3C组织机构的标准化下,JS全力支持了altered流和捕捉流,但现阶段旧版本的IE应用程序却是根本无法全力支持altered流(IE6,IE7,IE8均只全力支持altered流),因此为的是能相容更多的应用程序,提议他们采用altered流
●就像下面这个相片那样,他们点选在黄色箱子头上的与此同时,也是点选在了紫色箱子上
●这个是原先发展史事实,因此三个箱子的点选该事件单厢促发
●这个就叫作 该事件的散播也叫该事件流
●特别注意:天数散播的是该事件犯罪行为
○当原素促发三个该事件的这时候,其子原素也会促发完全相同的该事件,父原素的父原素也会促发完全相同的该事件
○就像下面的相片一样
○点选在黄色箱子上的这时候,会促发黄色箱子的点选该事件
○也是点选在了紫色的箱子上,也会促发紫色箱子的点选该事件
○也是点选在了 body 上,也会促发 body 的点选该事件
○也是点选在了 html 上,也会促发 html 的点选该事件
○也是点选在了 document 上,也会促发 document 的点选该事件
○也是点选在了 window 上,也会促发 window 的点选该事件
○也就是说,页面上任何三个原素促发该事件,单厢一层一层最终导致 window 的完全相同该事件促发,前提是各层级原素得有注册完全相同的该事件,不然不会促发
●在该事件散播的过程中,有一些特别注意的点:
○只会散播同类型该事件,也就是说该事件类型要那样
○只会从点选原素开始按照 html 的结构逐层向上原素的该事件会被促发,也就是说要有结构上的父子级关系
○内部原素不管有没有该该事件,只要上层原素有该该事件,因此上层原素的该事件就会被促发
●到现在,他们已经了解了该事件的散播,他们再来思索三个难题
○该事件确实会从自己开始,到 window 的所有完全相同该事件单厢促发
○是因为他们点在自己头上,也确实逐层的点在了直至 window 的每三个原素头上
○但到底是先点在自己头上,还是先点在了 window 头上呢
○先点在自己头上,就是先继续执行自己的该事件处理函数,逐层向上最后继续执行 window 的该事件处理函数
○反之,则是先继续执行 window 的该事件处理函数,逐层向下最后继续执行自己头上的该事件处理函数
●该事件散播(该事件流)分为三个阶段:该事件捕捉阶段、天数目标阶段、该事件altered阶段<!DOCTYPE html> <html lang=“en”> <head> <meta charset=“UTF-8”> <meta name=“viewport” content=“width=device-width, initial-scale=1.0”> <meta http-equiv=“X-UA-Compatible” content=“ie=edge”> <title>Document</title> <style> * { margin: 0; padding: 0; } .outer { width: 500px;height: 500px; background-color: pink; position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto; }.center { width: 300px; height: 300px; background-color: skyblue; position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto; } .inner { width: 100px; height: 100px; background-color: orange; position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto; } </style> </head> <body> <div class=“outer”> <div class=“center”> <div class=“inner”></div> </div> </div> <script> var outer = document.querySelector(.outer) var center = document.querySelector(.center) var inner = document.querySelector(.inner) inner.onclick =function() { console.log(inner) } center.onclick = function() {console.log(center) } outer.onclick = function() { console.log(outer) } document.body.onclick = function() { console.log(body) } document.documentElement.onclick = function() { console.log(html) } document.onclick = function() { console.log(document) } window.onclick =function() { console.log(window) } </script> </body> </html>捕捉、目标、altered
●他们刚才聊过了,每三个该事件,都是有可能从自己到 window ,有可能要继续执行多个同类型该事件
●因此这个继续执行的顺序就有一些说法了捕捉阶段
●就是从 window 的该事件处理函数开始,依次向内,直到该事件 目标 的该事件处理函数继续执行
●也就是从上向下的继续执行该事件处理函数目标阶段
●你是点选在哪个原素头上了,因此这个该事件的 目标 就是对应的该原素
altered阶段
●就是从该事件 目标 的该事件处理函数开始,依次向外,直到 window 的### 该事件处理函数促发
●也就是从下向上的执行该事件处理函数●在该事件对象内有三个固定的信息表示本次该事件的该事件目标
●标准应用程序: 该事件对象.target
●IE 旧版本: 该事件对象.srcElement
●相容: 他们自己定义三个变量来相容
●var target = e.target || e.srcElement如何在捕捉阶段继续执行该事件
●DOM 0级 该事件绑定没有办法修改
●DOM 2级 该事件绑定才可以修改该事件的继续执行阶段
●通过 addEventListener() 的第三个参数来决定
○默认是 false, 表示altered阶段
○选填是 true, 表示捕捉阶段altered和捕捉的区别
●就是在该事件的散播中,多个同类型该事件处理函数的继续执行顺序不同
●在 IE 旧版本内根本无法按照altered的顺序来继续执行
●在标准应用程序下, 该事件默认是在altered阶段继续执行
●但可以选择在捕捉阶段继续执行<!DOCTYPE html> <html lang=“en”> <head> <meta charset=“UTF-8”> <meta name=“viewport” content=“width=device-width, initial-scale=1.0”> <meta http-equiv=“X-UA-Compatible” content=“ie=edge”> <title>Document</title> <style> * { margin: 0; padding: 0; } .outer { width: 500px; height: 500px; background-color: pink; position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto; } .center { width: 300px; height: 300px; background-color: skyblue; position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto; } .inner { width: 100px; height: 100px; background-color: orange;position: absolute; top: 0; left: 600px; right: 0; bottom: 0; margin: auto; } p { width: 100px; height: 100px; background-color: purple; position: absolute; left: 600px; top: 500px; } </style> </head> <body> <div class=“outer”> <div class=“center”> <div class=“inner”></div> </div> </div> <p></p> <script> // altered阶段继续执行 // 只要有 click 犯罪行为发生在 inner 头上就会促发对应的该事件处理函数 document.querySelector(.inner).addEventListener(click, function () { console.log(inner) }, false) document.querySelector(.center).addEventListener(click, function(){ console.log(center) }, false) document.querySelector(.outer).addEventListener(click, function () { console.log(outer) }, true) document.body.addEventListener(click, function () { console.log(body) }, false) document.documentElement.addEventListener(click, function () { console.log(html) }, false) document.addEventListener(click, function () { console.log(document) }, false) window.addEventListener(click, function () { console.log(window) }, false) // 捕捉阶段继续执行 document.querySelector(.inner).addEventListener(click, function () { console.log(inner) }, false) document.querySelector(.center).addEventListener(click, function () { console.log(center) }, false) document.querySelector(.outer).addEventListener(click, function () { console.log(outer) },false) document.body.addEventListener(click, function () { console.log(body) }, false) document.documentElement.addEventListener(click, function () { console.log(html) }, false) document.addEventListener(click, function () { console.log(document) }, false) window.addEventListener(click, function () { console.log(window) },false) </script> </body> </html>阻止该事件散播和默认犯罪行为
阻止该事件散播(捕捉和altered)
●在有的情况下他们不需要该事件的散播,就是实现自己的功能就好,这就需要阻止该事件的散播
标准浏览器
●语法:该事件对象.stopPropagtion()
●作用: 该事件不管是 altered监督机制 却是 捕捉监督机制 到自己位置, 不在继续散播了IE旧版本应用程序
●语法:天数对象.cancelBubble = ture
●作用: 取消该事件的altered相容写法
●这里的相容不能在采用逻辑运算符||,会报错
●这里可以用try {} catch() {} 语法
○首先继续执行 try 后面的 {} 内部的代码
○如果代码没有报错, 因此 catch 就不继续执行了
○如果代码报错了, 因此继续执行 catch 内部的代码try { // 当这里的代码报错的这时候, 不会在控制台显示 // 也不会阻断程序的继续继续执行 // 而是把错误信息给到 err 参数 // 继续去继续执行 catch 内的代码 console.log(abc) } catch(err) { console.log(try 里头的代码报错了) console.log(err) }<!DOCTYPE html> <html lang=“en”> <head> <meta charset=“UTF-8”> <meta name=“viewport” content=“width=device-width, initial-scale=1.0”> <meta http-equiv=“X-UA-Compatible” content=“ie=edge”> <title>Document</title> <style> div { width: 500px; height: 500px; background-color: pink; } p { width: 300px; height: 300px; background-color: skyblue; } </style> </head> <body> <div> <p></p> </div> <script> var div = document.getElementsByTagName(div)[0] var p = document.getElementsByTagName(p)[0] p.onclick = function(e) { // 事件对象相容 e = e || window.event // try … catch 语法进行相容 try { e.stopPropagation() } catch(err) { e.cancelBubble =true } console.log(p) } div.onclick = function() { console.log(div) } </script> </body> </html>阻止默认犯罪行为
●默认犯罪行为,就是不用他们注册,它自己就存在的事情
○比如他们点选鼠标右键的这时候,会自动弹出三个菜单
○比如他们点选 a 标签的这时候,他们不需要注册点选该事件,他自己就会跳转页面
○还有form表单就有自动提交功能
○…
●这些不需要他们注册就能实现的事情,他们叫作 默认该事件也叫默认犯罪行为
●有的这时候,他们不希望应用程序继续执行默认该事件
○比如我给 a 标签绑定了三个点选该事件,我点选你的这时候希望你能告诉我你的地址是甚么
○而不是直接跳转链接
○因此他们就要把 a 标签原先的默认该事件阻止,不让他继续执行默认该事件
●他们有三个方法来阻止默认该事件标准应用程序
●语法:该事件对象.preventDefault()
IE旧版本应用程序
●语法:该事件对象.returnValue = false相容写法
●这里的相容不能在采用逻辑运算符 ||,会报错
●这里可以用try {} catch() {} 语法
○首先继续执行 try 后面的 {} 内部的代码
○如果代码没有报错, 因此 catch 就不继续执行了
○如果代码报错了, 因此继续执行 catch 内部的代码通用写法
●直接书写 return false
○这个代码必须写在最后一行
○必须保证前面的代码百分之一百没有错误<!DOCTYPE html> <html lang=“en”> <head> <meta charset=“UTF-8”> <meta name=“viewport” content=“width=device-width, initial-scale=1.0”> <meta http-equiv=“X-UA-Compatible” content=“ie=edge”> <title>Document</title> </head> <body> <a href=“https://www.jd.com”>你好</a> <script> var a = document.getElementsByTagName(a)[0] a.onclick = function(e) { // 处理该事件对象相容 e = e || window.event // 相容 try { e.preventDefault() } catch (err) { e.returnValue = false } console.log(hello world) // 通用的方式 // return false } </script> </body> </html>该事件委托
●就是把我要做的事情委托给别人来做
●因为他们的altered监督机制,点选子原素的这时候,也会同步促发父原素的完全相同该事件
●因此他们就可以把子原素的该事件委托给父原素来做
●给多个原素添加完全相同的该事件,可以把这个该事件添加给上级原素。原理就的该事件altered
该事件促发
●点选子原素的这时候,不管子原素有没有点选该事件,只要父原素有点选该事件,因此就可以促发父原素的点选该事件<body> <ul> <li>1</li> <li>2</li> <li>3</li> </ul> <script> varoUl = docuemnt.querySelector(ul) oUl.addEventListener(click, function (e) { console.log(我是 ul 的点选该事件,我被促发了) })</script> </body>●像下面一段代码,当你点选 ul 的这时候肯定会促发
●但当你点选 li 的这时候,其实也会促发target
●target 这个属性是该事件对象里头的属性,表示你点选的目标
●当你促发点选该事件的这时候,你点选在哪个原素上,target 就是哪个原素
●这个 target 也不相容,在 IE 下要采用 srcElement<body> <ul> <li>1</li> <li>2</li> <li>3</li> </ul> <script> var oUl = docuemnt.querySelector(ul) oUl.addEventListener(click, function (e) { e = e || window.event var target = e.target || e.srcElement console.log(target) })</script> </body>●下面的代码,当你点选 ul 的这时候,target 就是 ul
●当你点选在 li 下面的这时候,target 就是 li委托
●这个这时候,当他们点选 li 的这时候,也可以促发 ul 的点该事件
●因此在该事件内不,他们也可以拿到你点选的到底是 ul 却是 li
●这个这时候,他们就可以把 li 的该事件委托给 ul 来做<body> <ul> <li>1</li> <li>2</li> <li>3</li> </ul> <script> var oUl = docuemnt.querySelector(ul) oUl.addEventListener(click, function (e) { e = e || window.event var target = e.target || e.srcElement // 判断你点选的是 li if (target.nodeName.toUpperCase === LI) { // 确定点选的是 li // 因为当你点选在 ul 下面的这时候,nodeName 应该是 UL // 去做点选 li 的这时候该做的事情了 console.log(我是 li,我被点选了) } }) </script> </body>●下面的代码,他们就可以把 li 要做的事情委托给 ul 来做
总结
●为甚么要用该事件委托
○我页面上本身没有 li
○我通过代码添加了一些 li
○添加进来的 li 是没有点选该事件的
○我每次动态的操作完 li 以后都要从新给 li 绑定一次点选该事件
○比较麻烦
○这个这时候只要委托给 ul 就可以了
○因为新加进来的 li 也是 ul 的子原素,点选的这时候也可以促发 ul 的点选该事件
●该事件委托的书写
○原素的该事件根本无法委托给结构父级或者再结构父级的同样的该事件上
○li 的点选该事件,就不能委托给 ul 的鼠标移入该事件
○li 的点选该事件,根本无法委托给 ul 或者在高父级的点选该事件上