js中preventDefault和stopPropagation两个方法的区别

本文详细解释了JavaScript中preventDefault和stopPropagation两个关键方法的作用及区别。preventDefault用于阻止元素的默认行为,如阻止链接跳转;stopPropagation则用于阻止事件冒泡,避免事件在DOM树中向上层传播。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先讲解一下js中preventDefault和stopPropagation两个方法的区别:

     preventDefault方法的起什么作用呢?我们知道比如<a href="http://www.baidu.com">百度</a>,这是html中最基础的东西,起的作用就是点击百度链接到http://www.baidu.com,这是属于<a>标签的默认行为,而preventDefault方法就是可以阻止它的默认行为的发生而发生其他的事情。看一段代码大家就明白了:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>JS阻止链接跳转</title>
<script type="text/javascript"> 
function stopDefault( e ) { 
     if ( e && e.preventDefault ) 
        e.preventDefault(); 
    else 
        window.event.returnValue = false; 
        
    return false; 
} 
</script> 
</head>
<body>
<a href="http://www.baidu.com"id="testLink">百度</a> 
<script type="text/javascript"> 
var test = document.getElementById('testLink'); 
test.onclick = function(e) { 
   alert('我的链接地址是:' + this.href + ', 但是我不会跳转。'); 
   stopDefault(e); 
} 
</script>
</body>
</html>


此时点击百度链接,不会打开http://www.baidu.com,而只是弹出一个alert对话框。

     preventDefault方法讲解到这里,stopPropagation方法呢?讲stopPropagation方法之前必需先给大家讲解一下js的事件代理。

      事件代理用到了两个在JavaSciprt事件中常被忽略的特性:事件冒泡以及目标元素。当一个元素上的事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发。这一过程被称为事件冒泡;这个事件从原始元素开始一直冒泡到DOM树的最上层。对任何一个事件来说,其目标元素都是原始元素,在我们的这个例子中也就是按钮。目标元素它在我们的事件对象中以属性的形式出现。使用事件代理的话我们可以把事件处理器添加到一个元素上,等待事件从它的子级元素里冒泡上来,并且可以很方便地判断出这个事件是从哪个元素开始的。

     stopPropagation方法就是起到阻止js事件冒泡的作用,看一段代码。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML1.0 Transitional//EN" "http://www.w3.org/TR/xHTML1/DTD/xHTML1-transitional.dtd">
<HTML XMLns="http://www.w3.org/1999/xHTML"lang="gb2312">
<head>
<title> 阻止JS事件冒泡传递(cancelBubble、stopPropagation)</title>
<meta name="keywords" content="JS,事件冒泡,cancelBubble,stopPropagation" />
<script>
function doSomething (obj,evt) {
alert(obj.id);
var e=(evt)?evt:window.event;
if (window.event) {
   e.cancelBubble=true;     // ie下阻止冒泡
} else {
   //e.preventDefault();
   e.stopPropagation();     // 其它浏览器下阻止冒泡
}
}
</script>
</head>
<body>
<div id="parent1" onclick="alert(this.id)"style="width:250px;background-color:yellow">
<p>This is parent1 div.</p>
<div id="child1" onclick="alert(this.id)"style="width:200px;background-color:orange">
   <p>This is child1.</p>
</div>
<p>This is parent1 div.</p>
</div>
<br />
<div id="parent2" onclick="alert(this.id)"style="width:250px;background-color:cyan;">
<p>This is parent2 div.</p>
<div id="child2" onclick="doSomething(this,event);"style="width:200px;background-color:lightblue;">
   <p>This is child2. Will bubble.</p>
</div>
<p>This is parent2 div.</p>
</div>
</body>
</HTML>


大家运行一下上面的代码就明白了。

JS阻止冒泡出现(cancelBubble=true;与stopPropagation


function stoppropagation(){
	var e = e || window.event;
	if (e.stopPropagation) {
		e.stopPropagation();//标准的阻止冒泡
	}else{
		e.cancelBubble = true;//IE下阻止冒泡
	}
}


示例

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
</head>
<body>
<div onclick=alert("你好")style="background:red;width:350px;height:50px;">外层
    <span onclick=event.cancelBubble=false;style="background:green;margin:10px;height:30px;float:left;">内层 event.cancelBubble=false</span>
</div>
<div onclick=alert("你好")style="background:yellow;width:350px;height:50px;">外层
    <span onclick=event.cancelBubble=true;style="background:white;margin:10px;height:30px;float:left;">内层 event.cancelBubble=true</span>
</div>
</body>
</html>


 

<think>我们正在讨论如何阻止DOM事件冒泡默认行为。用户的问题是关于JavaScript中stopPropagationpreventDefault的用法。 根据引用[1],我们有一个阻止默认行为的例子:在touchmove事件中调用event.preventDefault()可以阻止默认的滑动行为。 引用[2]展示了事件捕获的例子,但并没有直接涉及阻止冒泡。 引用[3]提到事件解绑的注意事项,并指出匿名函数无法进行事件解绑,因为解绑时需要同一个函数引用。 用户的问题集中在两个方法: 1. event.stopPropagation() - 阻止事件冒泡(或捕获)传播 2. event.preventDefault() - 阻止事件的默认行为 我们需要解释这两个方法的用法区别,并给出示例。 步骤: 1. 解释stopPropagation:用于阻止事件在DOM树中进一步传播(包括冒泡阶段捕获阶段)。但注意,它不会阻止事件的默认行为。 2. 解释preventDefault:用于取消事件的默认行为(如果该行为可取消)。例如,点击链接的默认行为是跳转,表单提交的默认行为是提交表单等。 3. 注意:有些事件没有默认行为,所以调用preventDefault不会有任何效果。 示例代码: 阻止事件冒泡的示例: document.getElementById('child').addEventListener('click', function(event) { event.stopPropagation(); // 阻止事件冒泡到父元素 // 其他处理 }); document.getElementById('parent').addEventListener('click', function() { // 如果不阻止冒泡,点击子元素时这里也会触发 }); 阻止默认行为的示例: document.getElementById('myLink').addEventListener('click', function(event) { event.preventDefault(); // 阻止链接跳转 // 其他处理,比如异步加载内容 }); 4. 同时使用两个方法的情况: document.getElementById('myButton').addEventListener('click', function(event) { event.preventDefault(); // 阻止表单提交的默认行为(假设是type="submit"的按钮) event.stopPropagation(); // 阻止事件冒泡,避免触发父元素的点击事件 // 其他处理 }); 5. 注意:在事件处理函数中,我们可以通过return false来同时达到阻止冒泡阻止默认行为的效果吗? 在jQuery中,return false会同时调用preventDefaultstopPropagation。但是在原生JavaScript中,return false只会阻止默认行为,而不会阻止事件冒泡。因此,在原生JS中,我们不应该依赖return false来阻止冒泡。 6. 另外,引用[3]提到,使用匿名函数时无法解绑事件,因为需要同一个函数引用。因此,在需要解绑事件的场景,我们应该使用具名函数。 7. 我们可以引用[1]中的例子来展示preventDefault的用法,引用[3]来强调使用具名函数以便解绑。 8. 生成相关问题。 回答结构: 1. 介绍stopPropagationpreventDefault的作用。 2. 分别给出示例代码。 3. 讨论同时使用的情况。 4. 注意事项(如匿名函数解绑问题,return false的行为差异等)。 5. 生成相关问题。 注意:所有行内代码变量用$...$,独立公式用$$...$$(但本问题可能涉及较少数学公式,更多代码示例)。但根据指令,数学表达式需要用LaTeX,代码用代码块。</think>### JavaScript 中阻止事件冒泡与默认行为的方法 在 JavaScript 中,`stopPropagation()` `preventDefault()` 是两个核心的事件控制方法: #### 1. **`event.stopPropagation()` - 阻止事件冒泡** ```javascript element.addEventListener('click', function(event) { event.stopPropagation(); // 阻止事件向父元素传播 }); ``` **作用**: 阻止事件在 DOM 树中向上冒泡(从子元素到祖先元素),但不会影响当前元素的其他事件监听器执行[^2]。 **应用场景**: - 点击子元素时不触发父元素的点击事件 - 避免事件委托中的意外触发 #### 2. **`event.preventDefault()` - 阻止默认行为** ```javascript link.addEventListener('click', function(event) { event.preventDefault(); // 阻止链接跳转 }); ``` **作用**: 取消浏览器对事件的默认响应行为(如链接跳转、表单提交、滚动行为等)[^1]。 **应用场景**: - 阻止表单自动提交 - 禁用触摸滚动(移动端) - 自定义超链接行为 --- ### ⚠ 注意事项 1. **同时使用两个方法** ```javascript button.addEventListener('click', (event) => { event.preventDefault(); // 阻止默认提交 event.stopPropagation(); // 阻止冒泡到父容器 }); ``` 2. **事件解绑要求** 使用具名函数而非匿名函数,否则无法通过 `removeEventListener()` 解绑[^3]: ```javascript // 正确做法(具名函数) function handleClick(event) { event.stopPropagation(); } element.addEventListener('click', handleClick); element.removeEventListener('click', handleClick); ``` 3. **事件捕获阶段** 在捕获阶段(第三个参数设为 `true`)调用 `stopPropagation()` 会阻止事件向下传递: ```javascript parent.addEventListener('click', (event) => { event.stopPropagation(); // 阻止事件传递到子元素 }, true); ``` 4. **兼容性** 所有现代浏览器均支持这两个方法,包括移动端浏览器[^1]。 --- ### 完整示例 ```html <div id="parent"> 父区域 <a id="child" href="https://example.com">子链接</a> </div> <script> const parent = document.getElementById('parent'); const child = document.getElementById('child'); // 父元素监听(冒泡阶段) parent.addEventListener('click', () => { console.log('父元素被点击'); }); // 子元素监听 child.addEventListener('click', (event) => { event.preventDefault(); // 阻止链接跳转 event.stopPropagation(); // 阻止事件冒泡到父元素 console.log('子元素被点击,但不会跳转且不触发父元素'); }); </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值