JS中的事件冒泡与捕获
- 格式:docx
- 大小:76.33 KB
- 文档页数:6
js中阻⽌事件冒泡的⼏种⽅法前端开发过程中主要是通过以下三种⽅法来实现阻⽌事件冒泡<!DOCTYPE html><html lang="en" onclick="handleClickHtml()"><head><title>以这个html结构例举</title></head><body onclick="handleClickBody()"><div onclick="handleClickDiv()"><button id="btn1" onclick="handleClickBtn1(event)">我是⼀个btn1按钮preventDefault取消默认⾏为</button><button id="btn2" onclick="handleClickBtn2(event)">我是⼀个btn2按钮stopPropagation取消后续事件捕获和事件冒泡</button><button id="btn3" onclick="handleClickBtn3(event)">我是⼀个btn3按钮return false</button><button id="btn4" >我是⼀个btn4按钮函数式写法</button></div> </body><script>function handleClickBtn1(e){console.log(e);console.log('点击htn1');e.preventDefault();}function handleClickBtn2(e){console.log(e);console.log('点击htn2');e.stopPropagation();}function handleClickBtn3(e){console.log(e);console.log('点击htn3');return false}var btn4 = document.getElementById('btn4');btn4.onclick = function (e){console.log(e);console.log('点击htn4');return false};function handleClickDiv(){console.log('点击div');}function handleClickBody(){console.log('点击body');}function handleClickHtml(){console.log('点击html');}</script></html><!-- 事件冒泡的:如果在div中发⽣点击事件:那么click事件就在经过的结点上依次触发,button < div < body < html < document < window -->点击了⼀下btn按钮,结果它的整个dom结构的节点都依次触发了下⾯是三种处理事件冒泡的⽅法1.使⽤preventDefault();<button onClick={(e) => { e.preventDefault();}}>取消</button>使⽤ e.preventDefault()⽤于取消事件的默认⾏为,如果a标签的默认事件是href跳转,加了就不会跳转了2.使⽤stopPropapation();<button onClick={(e) => { e.stopPropagation();}}>取消</button>使⽤ e.stopPropagation()⽤于取消所有后续事件捕获和事件冒泡3.直接使⽤return false<button onClick={(e) => { return false;}}>取消</button>据说是使⽤这个就会直接调⽤ preventDefault和stopPropapation,TM的我⾃⼰使⽤这个居然没得⼀点效果,离谱,该冒的泡是⼀个都不会少啊事件流总共3个阶段:事件捕获,到达⽬标,事件冒泡事件捕获是从外层到⾥层到body这⼀层就结束,到达⽬标即触发事件的节点的过程⼀般是指body⾥的那⼀层,事件冒泡是从⾥层到外层。
js阻止输入框事件冒泡的方法JavaScript 是一种广泛使用的编程语言,它可以为网页添加各种动态效果和交互功能。
在网页开发中,文本输入框是常见的元素,用户可以在其中输入文本或数字等数据。
有时候我们希望当用户在输入文本框中键入文本时,不会触发其它 DOM 元素的事件。
本文将介绍 JS 阻止输入框事件冒泡的方法,希望能够帮助你更好地实现网页交互功能。
阻止事件冒泡的概念事件冒泡是指事件从最内层的元素开始发生,逐级向上传播到最外层的文档。
在页面中嵌套了多个元素,如果用户在最内层的元素中进行某个动作(比如点击、双击、拖拽等),则该事件会被依次传递给每个父元素进行处理。
这种一级一级往上冒泡的事件传播,就称为“事件冒泡”。
在前端开发中,如果不加以处理,事件冒泡可能会导致某个元素的事件被触发多次,导致不必要的问题和性能损失。
有时候我们需要阻止事件冒泡,即在内部元素触发事件时,停止该事件继续向上传递到外部元素。
阻止事件冒泡的方法在前端开发中,我们可以使用 JS 阻止事件冒泡,从而避免不必要的事件触发。
下面分别介绍两种常见的阻止事件冒泡的方法。
1. stopPropagation() 方法stopPropagation() 是 DOM 中 Event 对象的一个方法,可用于阻止事件冒泡。
当事件被触发时,Event 对象会自动传递到父元素,并逐级冒泡。
调用 stopPropagation()方法可以阻止该事件继续向上传递。
以下是一个简单的 HTML 页面,包含一个输入框和一个按钮:```html<input id="text-input" type="text" value="请输入内容" /><button id="submit-btn">提交</button>```如果我们希望在用户在输入框输入内容时,不触发按钮的点击事件,就可以在输入框的事件处理函数中调用 stopPropagation(),如下所示:```javascriptconst inputEl = document.querySelector('#text-input');const btnEl = document.querySelector('#submit-btn');inputEl.addEventListener('input', (event) => {event.stopPropagation(); // 阻止事件冒泡});btnEl.addEventListener('click', () => {console.log('按钮被点击了');});```在上述代码中,当用户在输入框中进行输入时,输入框的事件处理函数会被触发,并在处理函数中调用 stopPropagation() 方法。
JS阻止输入框事件冒泡的方法在网页开发中,我们经常会遇到需要对输入框进行事件处理的情况。
有时候,当我们在一个输入框中输入内容时,希望阻止事件冒泡到父元素或其他元素上,这就需要使用一些方法来实现。
本文将介绍几种常用的方法来阻止输入框事件冒泡。
1. 什么是事件冒泡在了解如何阻止输入框事件冒泡之前,我们先来了解一下什么是事件冒泡。
事件冒泡是指当一个元素触发了某个事件(例如点击),该事件会从触发元素开始向上级元素传递,直到传递到最顶级的文档对象。
这意味着如果你点击了一个按钮,按钮上绑定的点击事件会先被触发,然后再依次触发包含该按钮的父元素、祖先元素上绑定的相同类型的点击事件。
2. 阻止默认行为和阻止冒泡在讲解如何阻止输入框事件冒泡之前,我们需要先区分两个概念:阻止默认行为和阻止事件冒泡。
•阻止默认行为:指禁止浏览器对某个事件的默认处理。
例如,当你点击一个链接时,浏览器会自动跳转到链接指定的页面,你可以通过阻止默认行为来取消这个跳转行为。
•阻止事件冒泡:指阻止事件从当前元素向父级元素传递。
在实际应用中,我们通常需要同时阻止默认行为和阻止冒泡。
下面我们将介绍几种方法来实现这两个效果。
3. 使用Event对象的stopPropagation()方法在JavaScript中,每个事件都有一个对应的Event对象。
Event对象有一个名为stopPropagation()的方法,可以用于停止事件冒泡。
document.querySelector('input').addEventListener('click', function(event) {event.stopPropagation();});上述代码中,我们使用addEventListener()方法给输入框绑定了一个点击事件,并在事件处理函数中调用了stopPropagation()方法。
这样就可以阻止点击事件冒泡到父级元素或其他元素上。
js 面试题及答案JavaScript(简称 JS)是一种基于对象和事件驱动的脚本语言,常用于网页开发。
在进行JS开发时,经常需要面试来选择优秀的候选人。
本文将针对常见的JS面试题提供详细的答案,帮助读者更好地准备面试。
一、变量和数据类型1. 什么是变量?变量是用于存储和表示数据的一个名字。
在JS中,可以使用var、let或const关键字来声明一个变量。
2. 有哪些常见的数据类型?JS中有七种常见的数据类型,分别是:字符串(string)、数字(number)、布尔值(boolean)、对象(object)、数组(array)、Null和Undefined。
3. Null和Undefined有什么区别?Null表示一个空对象指针,也可以用于表示空值;Undefined表示一个未定义的值,即变量声明但未被赋值。
二、运算符和流程控制1. 请解释一下什么是短路求值。
短路求值是指在进行逻辑与(&&)和逻辑或(||)运算时,如果能根据前面的条件判断出最终结果,则停止执行后续的条件判断。
2. 请解释一下什么是深拷贝和浅拷贝。
深拷贝是指创建一个新的对像或数组,将原来对象或数组中的值完全复制到新对象或数组中。
浅拷贝是指将原对象或数组中的引用复制给新对象或数组。
3. 如何判断一个变量的具体数据类型?可以使用typeof运算符来判断一个变量的具体数据类型。
例如,typeof 5将返回"number"。
三、函数和作用域1. 什么是闭包?闭包是指一个函数能够访问和操作在其词法作用域外的变量。
2. 匿名函数和具名函数有什么区别?匿名函数没有名字,通常用于声明立即执行的函数。
具名函数则有名字,能够在定义后被多次调用。
3. 请解释一下什么是作用域链。
作用域链是指在函数执行期间,JS引擎按照函数的嵌套关系,从内层函数到外层函数依次查找变量的过程。
四、面向对象编程1. 什么是原型?原型链又是什么?每个对象都有一个原型对象,在没有定义某个属性或方法时会根据原型链进行查找。
js测试题及答案一、单选题(每题2分,共10分)1. JavaScript中,以下哪个是正确的变量声明方式?A. var name = "Kimi"B. name = "Kimi"C. const name = "Kimi"D. var name = Kimi答案:C2. 在JavaScript中,以下哪个是正确的函数声明?A. function myFunction() { }B. function myFunction() { return "Hello"; }C. var myFunction = function() { }D. All of the above答案:D3. 下列哪个选项是JavaScript中的全局对象?A. windowB. documentC. navigatorD. All of the above答案:D4. 在JavaScript中,以下哪个是正确的数组声明方式?A. var colors = "red", "green", "blue";B. var colors = ["red", "green", "blue"];C. var colors = new Array("red", "green", "blue");D. All of the above答案:D5. 下列哪个选项是JavaScript中的严格模式?A. "use strict";B. "use strict":C. 'use strict';D. All of the above答案:A二、多选题(每题4分,共20分)6. JavaScript中,以下哪些是合法的标识符?A. _variableB. 2variableC. $variableD. variable-答案:A, C7. 在JavaScript中,以下哪些是有效的数据类型?A. NumberB. StringC. BooleanD. Undefined答案:A, B, C, D8. 下列哪些是JavaScript中的对象?A. ArrayB. DateC. MathD. Function答案:A, B, C, D9. 在JavaScript中,以下哪些是正确的事件类型?A. clickB. loadC. submitD. error答案:A, B, C, D10. 下列哪些是JavaScript中的错误类型?A. SyntaxErrorB. TypeErrorC. ReferenceErrorD. Error答案:A, B, C, D三、判断题(每题2分,共10分)11. JavaScript是弱类型的语言。
事件(上)(不好意思,又是标题党)JavaScript事件列表事件解说一般事件onclick 鼠标点击时触发此事件ondblclick 鼠标双击时触发此事件onmousedown 按下鼠标时触发此事件onmouseup 鼠标按下后松开鼠标时触发此事件onmouseover当鼠标移动到某对象范围的上方时触发此事件onmousemove 鼠标移动时触发此事件onmouseout 当鼠标离开某对象范围时触发此事件onkeypress当键盘上的某个键被按下并且释放时触发此事件.onkeydown当键盘上某个按键被按下时触发此事件onkeyup当键盘上某个按键被按放开时触发此事件页面相关事件onabort 图片在下载时被用户中断onbeforeunload当前页面的内容将要被改变时触发此事件onerror 出现错误时触发此事件onload 页面内容完成时触发此事件onmove 浏览器的窗口被移动时触发此事件onresize当浏览器的窗口大小被改变时触发此事件onscroll浏览器的滚动条位置发生变化时触发此事件onstop浏览器的停止按钮被按下时触发此事件或者正在下载的文件被中断oncontextmenu 当弹出右键上下文菜单时发生onunload 当前页面将被改变时触发此事件表单相关事件onblur 当前元素失去焦点时触发此事件onchange当前元素失去焦点并且元素的内容发生改变而触发此事件onfocus 当某个元素获得焦点时触发此事件onreset当表单中RESET的属性被激发时触发此事件onsubmit 一个表单被递交时触发此事件了解上面的事件如此简单,那么事件还有什么可讲的呢?问题一:每个事件只能注册一个函数Js代码1var oDiv = document.getElementById("oDiv");2oDiv.onclick = fn1;3oDiv.onclick =fn2;4function fn1() {alert("我被覆盖了!")}5function fn2() {alert("只有我被执行到!")}解决方案一:Js代码6obj.onclick = function () {7 fn1();8 fn2();9 fn3();10};缺陷一:需要将所有函数一次添加进去,不能在运行时添加缺陷二:在事件处理函数中this将指向window,而不是obj解决方案二:Js代码11function addEvent(fn,evtype,obj) {12 //obj是要添加事件的HTML元素对象13 //evtype是事件名字,不包含on前缀,因为每个都有on,所以写个on是多余的14 //fn是事件处理函数15var oldFn;16if (obj["on"+evtype] instanceof Function) {17 oldFn = obj["on"+evtype];//当添加函数时,如果已注册过了,则将其保存起来18 }19 obj["on"+evtype]=function () {20if (oldFn) {21 oldFn.call(this);22 }23 fn.call(this);//使用call方法,使事件处理函数中的this仍指向obj24 };25}这样已经解决了问题,但如何删除事件呢?如果直接将对象的onevtype这类的属性赋值为null将会删除所有的事件处理函数!解决方案二的修改版:先将事件存储起来,存储在对象的__EventHandles属性里面Js代码26eventHandlesCounter=1;//计数器,将统计所有添加进去的函数的个数,0位预留作其它用27function addEvent(fn,evtype,obj) {28if(!fn.__EventID) {//__EventID是给函数加的一个标识,见下面给函数添加标识的部分29 fn.__EventID=eventHandlesCounter++;30 //使用一个自动增长的计数器作为函数的标识以保证不会重复31 }32if (!obj.__EventHandles) {33 obj.__EventHandles=[];//当不存在,也就是第一次执行时,创建一个,并且是数组34 }35if (!obj.__EventHandles[evtype]) {//将所有事件处理函数按事件类型分类存放36 obj.__EventHandles[evtype]={};//当不存在时也创建一个散列表37if (obj["on"+evtype] instanceof Function) {38 //查看是否已经注册过其它函数39 //如果已经注册过,则将以前的事件处理函数添加到下标为0的预留的位置40 obj.__EventHandles[evtype][0]=obj["on"+evtype];41 obj["on"+evtype]=handleEvents;//使用handleEvents集中处理所有的函数42 }43 }44 obj.__EventHandles[evtype][fn.__EventID]=fn;45 //如果函数是第一次注册为事件处理函数,那么它将被添加到表中,函数的标识作为下标46 //如果函数已经注册过相同对象的相同事件了,那么将覆盖原来的而不会被添加两次47function handleEvents() {48var fns = obj.__EventHandles[evtype];49for (var i in fns) {50 fns[i].call(this);51 }52 }53}使用上面的函数已经可以在一个对象添加多个事件处理函数,在函数内部this关键字也指向了相应的对象,并且这些函数都被作了标识,那么移除某个事件处理函数就是轻而易举的了!Js代码54//使用传统方法:obj.onevtype = null;但这样会移除所有的事件处理函数55function delEvent(fn,evtype,obj) {56if(!obj.__EventHandles || !obj.__EventHandles[evtype] || !fn.__EventID) {57return false;58 }59if (obj.__EventHandles[evtype][fn.__EventID] == fn) {60delete obj.__EventHandles[evtype][fn.__EventID];61 }62 }-------------------------------------------------新手的分隔线----------------------------------------------------------------事件(下)事件对象——Event事件对象是用来记录一些事件发生时的相关信息的对象。
js常见的面试题及答案1. 什么是闭包,它有什么作用?闭包是一个函数和声明该函数的词法环境的组合。
闭包的主要作用是允许一个函数访问其词法作用域之外的变量,即使在函数执行完毕后,这些变量依然可以被访问和操作。
2. 解释JavaScript中的原型继承。
JavaScript中的原型继承是通过原型链实现的。
每个对象都有一个原型对象,对象的属性和方法首先在自身查找,如果找不到,则沿着原型链向上查找,直到Object.prototype。
3. 如何判断一个变量是数组类型?可以使用`Array.isArray()`方法来判断一个变量是否是数组类型。
这是一个简单且推荐的方式。
4. 解释`var`、`let`和`const`之间的区别。
- `var`声明的变量具有函数作用域或全局作用域,并且存在变量提升。
- `let`声明的变量具有块级作用域,不存在变量提升。
- `const`声明的常量也具有块级作用域,并且一旦赋值后无法修改。
5. 什么是事件冒泡和事件捕获?事件冒泡是指事件从最具体的元素(事件的实际目标)开始,然后逐级向上传播到较为不具体的节点(通常是文档的根节点)。
事件捕获则是相反的过程,事件从最不具体的节点开始捕获,然后逐级向下传播到最具体的节点。
6. 解释JavaScript中的异步编程。
JavaScript中的异步编程允许代码在等待操作完成(如网络请求、文件读写等)的同时继续执行其他任务。
常见的异步编程模式包括回调函数、Promises和async/await。
7. 什么是深拷贝和浅拷贝?浅拷贝只复制对象的第一层属性,而深拷贝则递归复制对象的所有层级。
浅拷贝可能导致原始对象和拷贝对象共享引用,而深拷贝则创建了对象的完全独立的副本。
8. 解释JavaScript中的事件循环。
事件循环是JavaScript运行时环境的一部分,它负责管理异步任务的执行。
当一个异步任务(如setTimeout)被调度时,事件循环会在任务队列中等待,直到它被执行栈调用。
大学js考试题及答案一、选择题(每题2分,共20分)1. JavaScript中,用于声明变量的关键字是?A. varB. letC. constD. function答案:A2. 下列哪个选项不是JavaScript中的原始数据类型?A. NumberB. StringC. ObjectD. Boolean答案:C3. 以下哪个方法可以用来创建一个新的对象?A. new Object()B. {}C. Object.create()D. 以上都是答案:D4. 在JavaScript中,哪个函数可以用来将字符串转换为小写?A. toLowerCase()B. toUpperCase()C. toLocaleLowerCase()D. toLocaleUpperCase()答案:A5. 下列哪个选项是JavaScript中的全局对象?A. windowB. documentC. navigatorD. 以上都是答案:D6. 在JavaScript中,如何获取当前日期和时间?A. new Date()B. Date.now()C. Date()D. getTime()答案:A7. 以下哪个选项是JavaScript中用于数组的迭代方法?A. forEach()B. map()C. filter()D. 以上都是答案:D8. 在JavaScript中,如何判断一个变量是否是数组类型?A. Array.isArray()B. typeofC. instanceofD. 以上都是答案:A9. 下列哪个选项是JavaScript中用于创建函数的关键字?A. functionB. varC. letD. const答案:A10. 在JavaScript中,如何声明一个立即执行的函数表达式?A. (function() { ... })()B. function() { ... }()C. let x = function() { ... }D. 以上都是答案:A二、填空题(每题3分,共30分)1. 在JavaScript中,使用________关键字可以声明一个全局变量。
阻止事件冒泡的方法在网页开发中,我们经常会遇到需要阻止事件冒泡的情况。
事件冒泡是指事件被触发后,会从最内层的元素逐级向外层元素传播,直到传播到文档根节点。
有时候,我们希望阻止事件冒泡,以避免事件传播到不希望被触发的元素上。
本文将介绍几种常见的阻止事件冒泡的方法。
1. 使用stopPropagation()方法。
在JavaScript中,可以使用stopPropagation()方法来阻止事件冒泡。
这个方法是事件对象的一个方法,调用它可以阻止事件继续向父元素传播。
例如,当点击某个按钮时,我们希望阻止点击事件传播到父元素的div上,可以在按钮的点击事件处理函数中调用event.stopPropagation()来实现。
2. 使用return false。
在jQuery中,可以通过在事件处理函数中返回false来阻止事件冒泡。
例如,我们可以通过以下方式来阻止点击事件冒泡:```javascript。
$("button").click(function(event){。
// 阻止事件冒泡。
return false;});```。
这种方法和调用stopPropagation()方法的效果是一样的,都可以阻止事件向父元素传播。
3. 使用stopImmediatePropagation()方法。
除了stopPropagation()方法外,事件对象还提供了stopImmediatePropagation()方法,这个方法不仅可以阻止事件冒泡,还可以阻止事件的默认行为。
如果我们希望同时阻止事件冒泡和默认行为,可以使用stopImmediatePropagation()方法。
4. 在事件捕获阶段处理事件。
在DOM事件流中,事件有一个捕获阶段和一个冒泡阶段。
默认情况下,事件是在冒泡阶段处理的。
但是我们也可以在捕获阶段处理事件,并且在捕获阶段调用stopPropagation()方法来阻止事件冒泡。
2019前端试题及答案一、选择题(每题2分,共10分)1. HTML5中,用于定义文档的元信息的标签是:A. `<!DOCTYPE html>`B. `<html>`C. `<head>`D. `<meta>`答案:C2. CSS中,以下哪个属性用于设置文本的颜色?A. `font-color`B. `color`C. `text-color`D. `text-color`答案:B3. JavaScript中,用于声明变量的关键字是:A. varB. letC. constD. all of the above答案:D4. 在HTML中,以下哪个标签用于插入一个无序列表?A. `<ol>`B. `<ul>`C. `<dl>`D. `<dd>`答案:B5. 下列哪个选项不是JavaScript中的全局对象?A. windowB. documentC. MathD. String答案:D二、填空题(每题2分,共10分)1. 在HTML中,`<form>`标签用于创建一个______。
答案:表单2. CSS中,`display: none;`的作用是______。
答案:隐藏元素3. JavaScript中,`undefined`和`null`的区别是______。
答案:`undefined`表示未定义,`null`表示空值4. 在HTML5中,`<canvas>`标签用于______。
答案:绘制图形5. 使用JavaScript,`console.log()`函数用于______。
答案:输出信息到控制台三、简答题(每题5分,共20分)1. 请简述HTML5相对于HTML4的新特性。
答案:HTML5引入了新的语义标签,如`<article>`、`<section>`、`<header>`等,支持新的表单控件,如`<email>`、`<date>`等,增加了音频和视频支持,如`<audio>`、`<video>`标签,引入了2D和3D绘图API,以及对本地存储的支持等。
JS中的事件冒泡与捕获事件冒泡与捕获是DOM 中事件传播的两种方式,比如说对于注册了相同事件的两个DOM 元素(简单点就是两个div,一里一外),当点击里层div 的时候,这两个事件谁先执行。
冒泡事件,由里向外,最里层的元素先执行,然后冒泡到外层。
捕获事件,由外向里,最外层的元素先执行,然后传递到内部。
作者:songjz来源:segmentfault|2016-10-20 19:07收藏分享刚接触JS 的那个时候,啥也不懂,只想着如何利用Google、百度到的函数来解决实际的问题,不会想到去一探究竟。
渐渐的,对JS 的语言的不断深入,有机会去了解一些原理性东西。
最近在看JQuery 源码,感触很多,总想着用原生的JS 去实现自己的一个JQuery 库。
说实在的,JQuery 里面很多函数和思路,是千百开源工作者长期的贡献,哪能是短时间就能消化的了。
最近再次碰到addEventListener函数(MDN 上关于addEventListener 的介绍,很详细),由于之前并没有弄懂第三个参数的含义,要么默认值,要么手动设置成false。
这次看了不少文章,彻底把事件冒泡和捕获弄懂。
什么事件冒泡与捕获事件冒泡与捕获是DOM 中事件传播的两种方式,比如说对于注册了相同事件的两个DOM 元素(简单点就是两个div,一里一外),当点击里层div 的时候,这两个事件谁先执行。
冒泡事件,由里向外,最里层的元素先执行,然后冒泡到外层。
捕获事件,由外向里,最外层的元素先执行,然后传递到内部。
在IE 9 之前是只支持事件冒泡,IE 9(包括IE 9) 之后和目前主流的浏览器都同时支持两种事件。
如何设置,只需修改addEventListener的第三个参数,true 为捕获,false 为冒泡,默认为冒泡。
举个简单的例子,1. <div>2. <span class="out">3. <span class="in"></span>4. </span>5. </div>6. <script type="text/javascript">7. var dom_out = document.getElementsByClassName('out')[0];8. var dom_in = document.getElementsByClassName('in')[0];9. dom_out.addEventListener('click',function(){10. alert('out');11. },false);12. dom_in.addEventListener('click',function(){13. alert('in');14. },false);15. </script>在上面这个例子中,事件是按照冒泡来执行的,点击里层的in,会看到先alert 的顺序是先"in" 后"out",如果把事件改成捕获,alert 的顺序又不一样了。
1. <script type="text/javascript">2. var dom_out = document.getElementsByClassName('out')[0];3. var dom_in = document.getElementsByClassName('in')[0];4. dom_out.addEventListener('click',function(){5. alert('out');6. },true);7. dom_in.addEventListener('click',function(){8. alert('in');9. },true);10. </script>上面这个例子是捕获事件的例子,点击in效果是不是不一样呢?之所以会有冒泡和捕获事件(像IE 9 之前的浏览器不支持捕获事件,还真是反程序员),毕竟在实际中处理事情肯定有个先后顺序,要么由里向外,要么由外向里,两者都是必须的。
但有时候为了兼容IE 9 以下版本的浏览器,都会把第三个参数设置成false 或者默认(默认就是false)。
进一步理解冒泡和捕获现在已经说清楚冒泡和捕获,那么如果同时出现冒泡和捕获会出现什么结果?原来浏览器处理时间分为两个阶段,捕获阶段和冒泡阶段,∙先执行捕获阶段,如果事件是在捕获阶段执行的(true 情况),则执行;∙然后是冒泡阶段,如果事件是在冒泡阶段执行的(false 情况),则执行;来看一看例子就知道了:1. <div>2. <span class="s1">s13. <span class="s2">s24. <span class="s3">s35. </span>6. </span>7. </span>8. </div>这次我们设置三个span,分别是s1, s2, s3,然后设置s1,s3 为冒泡执行,s2 为捕获执行:1. <script type="text/javascript">2. var s1 = document.getElementsByClassName('s1')[0];3. var s2 = document.getElementsByClassName('s2')[0];4. var s3 = document.getElementsByClassName('s3')[0];5. s1.addEventListener('click',function(){6. alert('s1');7. },false);8. s2.addEventListener('click',function(){9. alert('s2');10. },true);11. s3.addEventListener('click',function(){12. alert('s3');13. },false);14. </script>从运行的效果来看,点击s3,依次alert s2 => s3 => s1,说明:∙捕获事件和冒泡事件同时存在的,而且捕获事件先执行,冒泡事件后执行;∙如果元素存在事件且事件的执行时间与当前逻辑一致(冒泡或捕获),则执行。
默认事件取消与停止冒泡当然,有时候我们只想执行最内层或最外层的事件,根据内外层关系来把范围更广的事件取消掉(对于新手来说,不取消冒泡,很容易中招的出现bug)。
event.stopPropagation()(IE 中window.event.cancelBubble = true)可以用来取消事件冒泡。
有时候对于浏览器的默认事件也需要取消,这时候用到的函数则是event.preventDefault()(IE 中window.event.returnValue = false)。
那么默认事件取消和停止冒泡有什么区别呢?我的理解:浏览器的默认事件是指浏览器自己的事件(这不废话吗),比如 a 标签的点击,表单的提交等,取消掉就不会执行啦;冒泡则取消的是由外向里(捕获)、由里向外(冒泡),stop 之后,就不会继续遍历了。
stackoverflow 上的解答看下例子,依旧是上面那个例子,不过每个函数都加了停止冒泡:1. s1.addEventListener('click',function(e){2. e.stopPropagation();3. alert('s1');4. },false);5. s2.addEventListener('click',function(e){6. e.stopPropagation();7. alert('s2');8. },true);9. s3.addEventListener('click',function(e){10. e.stopPropagation();11. alert('s3');12. },false);点击的结果是:当点击s2 或s3 的时候,都会alert s2,点击s1,弹出s1。
因为事件被取消的缘故,点击s3,执行s2后就不会在向下执行了。
在看一个preventDefault 的例子。
1. <div>2. <a href="/">点我回主页</a>3. </div>4. <div>5. <a href="/" class="back">点我不回主页</a>6. </div>7. <script type="text/javascript">8. var back = document.getElementsByClassName('back')[0];9. back.addEventListener('click', function(e){10. e.preventDefault();11. });12. </script>第二个链接是不是回不了主页,因为浏览器的默认事件被取消了。
以上所有例子请在非低版本IE 浏览器的环境下浏览O_o总结总结就补充两个兼容IE 的函数吧:1. function stopBubble(e) {2. //如果提供了事件对象,则这是一个非IE浏览器3. if ( e && e.stopPropagation )4. //因此它支持W3C的stopPropagation()方法5. e.stopPropagation();6. else7. //否则,我们需要使用IE的方式来取消事件冒泡8. window.event.cancelBubble = true;9. }10. //阻止浏览器的默认行为11. function stopDefault( e ) {12. //阻止默认浏览器动作(W3C)13. if ( e && e.preventDefault )14. e.preventDefault();15. //IE中阻止函数器默认动作的方式16. else17. window.event.returnValue = false;18. return false;19. }共勉!参考stackoverflow 什么是事件冒泡和捕捉stackoverflow stopPropagation 和preventDefault 的区别MDN addEventListenerjavascript阻止事件冒泡和浏览器的默认行为【编辑推荐】1.JavaScript数组中的indexOf方法2.DOM事件深入浅出(一)3.DOM事件深入浅出(二)4.JavaScript奇味探索5.JavaScript函数式真正的浅析。