澳门百老汇游戏 服务器常用软件

澳门百老汇游戏报道js基础之事情捕获与冒泡原理_澳门百老汇游戏官网资讯

 更新时间:2019年10月09日 08:32:56   作者:夕山雨   我要议论
这篇文章主要为大家详细介绍了js基础之事情捕获与冒泡原理,文中示例代码介绍的非常详细,具有肯定的参考价值,感兴趣的小伙伴们能够参考一下

想要了解什么是事情捕获与冒泡,需要先了解什么是事情。

什么是事情?

我们知道,在前端开拓中,JavaScript认真定义网页的“行为”。这里所说的“定义”,本来指的是开拓者能够通过JavaScript语言向扫瞄器描述一些法则,扫瞄器按照这些法则与用户进行交互。比如开拓者希望当用户点击页面上某个按钮的时刻,就弹出一个窗口,显示特定的内容。而当用户真正点击这个按钮的时刻,扫瞄器将按照开拓者定义的这个法则,去弹出指定的窗口,显示指定的内容。

在上面的例子中,扫瞄器是一切法则的执行者,开拓者是这些法则的制定者,而JavaScript只是开拓者向扫瞄器描述这些法则时所使用的的语言(否则扫瞄器无法知道开拓者想要在什么情况下做什么事)。假如我们通过以下的语句向扫瞄器描述了一条法则:

<body>
 <button id="btn">点击</button>
 <script>
 var button = document.getElementById("btn"); //猎取页面上的按钮
 button.addEventListener("click", function(){ //定义点击事情
 alert("我被点击了");
 })
 </script>
</body>

页面上现在有一个按钮,我们首先使用原生DOM猎取这个按钮,然后使用button.addEventListener(“click”, function(){})这样的语法向扫瞄器描述了一条法则:当这个按钮被点击(click)时,弹出提示框,显示“我被点击了”。用户点击按钮后网页就会出现如下提示:

扫瞄器把这次“点击”称为一个“事情”。“事情”用于描述交互进程中某些特定的关键点(如点击、鼠标滑动、滚轮滚动、按下键盘、触屏操作等,每个操作都对应特定的事情,不外事情也可能与用户行为无关,比如网页加载完毕也是一个事情)。而扫瞄器处置交互最重要的手段就是基于事情来执行开拓者定义好的回调函数(如在用户“点击按钮”时“弹出窗口”,而定义“弹出窗口”行为的就是回调函数,也就是addEventListener中的function)。

定义完这条法则,当用户点击按钮时,扫瞄器就会弹出上述窗口了。我们称“点击”这个事情是在这个按钮上触发的(因为我们的回调函数是绑定在这个按钮上的)。

那什么是事情的捕获与冒泡呢?

事情的捕获与冒泡

这个问题与HTML的结构息息相关。

在前端开拓中,我们使用标签语言HTML来描述网页结构,如一个标题、一个段落、一个表格等,这些网页元素描述了网页上有哪些需要显示的内容,它们构成了整个网页的“骨骼”,通常是一种嵌套的结构,比如:

<html>
 <head>
 ... //这是对网页内容的元描述
 </head>
 
 <body> //这是网页需要渲染的真正内容
 <div>
  <h1>标题</h1>
  <p>这里是一个段落</p>
 </div>
 </body>
</html>

上述网页结构示意图如下(在没有设置padding等属性的情况下,子元素通常会填满父元素,这里的内间距只是为了说明元素的嵌套联系):

我们看到,body元素是整个网页的容器,它的内部包含了一个div元素,而div的内部又包含了两个元素:h1和p。假如我们现在在p的内部点击了一下,那么请问我们有没有点击它的外部容器div,以及最外部的body呢?

从扫瞄器的角度来看,我们同时在点击这三个元素。

想要证明这个结论非常简单,只需要使用addEventListener向div和body各自绑定click事情,如果点击p时也会被触发,那就说明上面的结论是正确的。毫无疑问,它们会被触发。

那么问题来了,既然用户同时在点击这三个元素,扫瞄器应该先执行哪个元素定义的回调函数呢(由于JavaScript采纳单线程模型,执行回调函数必定有肯定的先后顺次)?

这个问题实际上是在说,对付嵌套的元素,应该从内向外还是从外向内响应事情。扫瞄器之争的两大对立方分别有自己的看法:Netscape腾博会怎么赢钱认为应当由最外层的body首先得到这个事情,其次是div,最后才是目的元素p;而微软的IE开拓组则认为,应当是内部的p首先得到这个事情,然后是div,最后才是body。在没有标准约束的情况下,两者按照自己的想法去设计扫瞄器的事情模型,Netscape从外向内流传的模型在业内被称为事情捕获模型,而微软从内向外流传的模型则被称为事情冒泡模型。

两个模型虽然从思路上南辕北辙,但是都能够保证一切绑定的回调函数正确触发(不外触发顺次是相反的。如果这个触发顺次很重要,那么在当时,你的代码可能只能在一个扫瞄器中正确运行,或者去做恶心的扫瞄器兼容)。不外扫瞄器同意开拓者在事情流传的进程中阻止事情的继续流传,此时两者的差异就变得极其显著。

假如我们在定义点击div元素的回调函数时阻止了事情的流传:

div.addEventListener("click", function(e){
 ...
 e.stopPropagation(); //阻止事情继续流传
})

这个代码会在两种模型下发生巨大的差异。在捕获模型中,由于最外部首先得到该事情,因此body的点击事情首先被触发,之后是div的点击事情。由于阻止了事情流传,p元素不会触发回调。而在冒泡模型中则恰恰相反,内部的p首先得到该事情,其次才是div,因此触发回调的将是p和div,body因为事情没有冒泡上来而无法监听到该事情。同样的代码在两种模型中发生了完全差别的行为,这对付开拓者来说显然是不可接收的(两个模型都有自己的适用场景,也都有自己的合理性,因此对付模型的好坏不克一概而论)。

那么以后的国际标准组织是如何解决这个冲突的呢?答案就是由开拓者自己选择。

标准的事情绑定使用addEventListener函数,它接收两个必传参数和一个可选参数:必传的为event(事情名,如"cick")和function(回调函数),可选的为useCapture(是否使用捕获模型,默认为false,依据MDN的接口说明,这里也能够传入一个工具,为本次监听设置别的参数,详细请参考MDN接口文档 - addEventListener)。

div.addEventListener("click", function(){}, true); //使用捕获模型

第三个参数就是标识开拓者是否需要使用捕获模型,默认为false,也就是默认使用微软的冒泡模型(这是因为大多数事情都只在最内部的元素上触发,这也间接表明,冒泡模型的普适性更好)。如果开拓者的需求确实需要使用捕获模型,能够将第三个参数设置为true。比如下面的例子:

事情捕获与冒泡的用法

了解了事情捕获与冒泡的基本原理之后,我们举个例子来说明这两个模型的基本用法。

假设有以下的DOM结构:

<div id="outer">
 <div id="inner" style="width:100px;height: 100px;border: 1px solid black;">
 
 </div>
 </div>

这是两个重叠的div,当点击时,两者都会响应这个click事情。假如事情绑定如下:

var outer = document.querySelector("#outer");
var inner = document.querySelector("#inner");
 outer.addEventListener("click", function(e){
 alert("来自外部div的消息");
 e.stopPropagation(); //阻止事情向内部流传
 }, true); //使用捕获模型

 inner.addEventListener("click", function(e){
 alert("来自内部div的消息");
 }, true); //使用捕获模型

页面上将只显示外部弹出的消息,内部的事情被e.stopPropagation()拦截了下来,导致事情没有触发。而如果写成下面的代码:

var outer = document.querySelector("#outer");
var inner = document.querySelector("#inner");
 outer.addEventListener("click", function(e){
 alert("来自外部div的消息");
 }, false); //使用冒泡模型

 inner.addEventListener("click", function(e){
 alert("来自内部div的消息");
 e.stopPropagation(); //阻止事情向外部流传
 }, false); //使用冒泡模型

这次是只显示了内部的消息,而没有显示外部的消息,说明事情在向上冒泡的进程中被阻止了。

注意

如果是在表格中内嵌复选框,希望实现点击一行时选中复选框,通过stopPropagation阻止CheckBox响应click事情并不克实现。测验发现复选框状态改变的事情似乎并不是在click事情触发的(断点跟踪表明,CheckBox在执行click回调之前,状态就已经发生了改变,具体是通过什么事情改变了选中状态尚不清楚),下面给一个能够处置行点击的示例:

<table border="1" cellspacing="0">
 <tr class="tr">
 <td>
 <input class="checkbox" type="checkbox">
 
 </td>
 <td>
 表格第一行
 </td>
 </tr>
 <tr class="tr">
 <td>
 <input class="checkbox" type="checkbox">
 </td>
 <td>
 表格第二行
 </td>
 </tr>
</table>
<script>
 var tr = document.querySelectorAll(".tr"); //猎取一切tr
 tr.forEach(function(item){ //为每个tr绑定click事情,手动选中复选框
 item.addEventListener("click", function(e){
 var checkbox = item.querySelector(".checkbox");
 checkbox.checked = !checkbox.checked;
 })
 })

 var cb = document.querySelectorAll(".checkbox");
 cb.forEach(function(item){
 item.addEventListener("click", function(e){
 this.checked = !this.checked;
 });
 })
</script>

这里没有使用stopPropagation阻止事情流传,而是通过为CheckBox定义额外的click事情来解决状态稳定的问题(通过断点跟踪,此时在点击CheckBox时,状态发生了三次变化,第一次是触发了某个原生事情导致其状态变化,第二次是执行了tr的点击事情,第三次则是为CheckBox自定义的click事情)。也就是说,点击tr时状态改变一次,点击CheckBox时状态改变三次,功能均正常。

由于在大多数情况下,事情都是由最内层的元素来处置的,所以冒泡模型的应用更为普遍,它也因此成为绑定事情时使用的默认模型。

总结

事情的捕获与冒泡两个模型相对角较简单,只要明白了其中的原理,就能够很容易掌握通过stopPropagation阻止事情流传的使用。

扫瞄器的标准事情模型把事情的流传进程分成了三个阶段:捕获阶段、处于目的阶段和冒泡阶段。捕获阶段指事情从最外层流传到最内层之前的整个进程,对应捕获模型;处于目的阶段指的是事情刚好流传到目的元素上;而冒泡阶段指的是从最内层元素向外流传的整个进程。所以我们看到,标准的扫瞄器事情模型就是把捕获模型和冒泡模型有机地结合起来,使开拓者能够以最简单的方式机动地使用两个模型。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多撑腰澳门百老汇游戏。

  • js
  • 事情捕获
  • 事情冒泡

相关文章

  • 微信小程序t6娱乐平台登录轮播组件gallery slider使用方法详解

    微信小程序t6娱乐平台登录轮播组件gallery slider使用方法详解

    这篇文章主要为大家详细介绍了微信小程序t6娱乐平台登录轮播组件gallery slider的使用方法,具有肯定的参考价值,感兴趣的小伙伴们能够参考一下
    2018-01-01
  • JavaScript实现的简单拖拽效果

    JavaScript实现的简单拖拽效果

    这篇文章主要介绍了JavaScript实现的简单拖拽效果,涉及javascript针对鼠标事情与页面样式的操作技术,需要的朋友能够参考下
    2015-06-06
  • ES6中的rest参数与扩展运算符详解

    ES6中的rest参数与扩展运算符详解

    rest参数和扩展运算符都是ES6新增的特性。下面这篇文章主要给大家介绍了瑞丰娱乐 国际娱乐ES6中rest参数与扩展运算符的相关资料,文中通过示例代码介绍的非常详细,对大家具有肯定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-07-07
  • js动态挪用css属性的小纪律及实例说明

    js动态挪用css属性的小纪律及实例说明

    本篇文章主要介绍了js动态挪用css属性的小纪律及实例说明。需要的朋友能够过来参考下,希望对大家有所帮助
    2013-12-12
  • JavaScript作用域、闭包、工具与原型链概念及用法实例总结

    JavaScript作用域、闭包、工具与原型链概念及用法实例总结

    这篇文章主要介绍了JavaScript作用域、闭包、工具与原型链,结合实例形式总结分析了javascript中变量与函数的作用域、闭包、工具、原形链相关概念、用法及注意事项,需要的朋友能够参考下
    2018-08-08
  • JS自定义选项卡函数及用法实例分析

    JS自定义选项卡函数及用法实例分析

    这篇文章主要介绍了JS自定义选项卡函数及用法,以实例形式较为详细的分析了javascript自定义tab切换函数及使用方法,具有肯定参考借鉴价值,需要的朋友能够参考下
    2015-09-09
  • React中this遗失的四种解决方法

    React中this遗失的四种解决方法

    这篇文章主要给大家介绍了瑞丰娱乐 国际娱乐React中this遗失的四种解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者使用React具有肯定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  • JS计算斐波拉切代码实例

    JS计算斐波拉切代码实例

    这篇文章主要介绍了js计算斐波拉切,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有肯定的参考学习价值,需要的朋友能够参考下
    2019-09-09
  • JavaScript仿照Pinterest实现t6娱乐平台登录预加载功能

    JavaScript仿照Pinterest实现t6娱乐平台登录预加载功能

    t6娱乐平台登录预加载是web开拓中一种应用相当普遍的技术,比如我们在做t6娱乐平台登录翻转显示等特效的时刻,为了让t6娱乐平台登录在转换的时刻不出现守候,我们最好是先让t6娱乐平台登录下载到本地,然后在继续执行后续的操作。今天本文主要介绍的是使用JS仿照Pinterestt6娱乐平台登录社交网站的t6娱乐平台登录预加载功能。
    2016-10-10
  • 微信小程序-form表单提交代码实例

    微信小程序-form表单提交代码实例

    这篇文章主要介绍了微信小程序-form表单提交,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有肯定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04

最新议论

微信 澳门老虎机开户体验金 投诉建议 在线工具
条评论