在JavaScript 如何阻止事件冒泡和事件默认行为?

大白话 在JavaScript 如何阻止事件冒泡和事件默认行为?

引言

凌晨两点,测试小姐姐发来一段录屏:用户点击页面底部的“返回顶部”按钮,结果不仅触发了返回顶部,还顺带提交了旁边的表单,甚至把整个页面的弹窗都给关掉了。你盯着代码里的三个click事件绑定,冷汗瞬间浸湿了后背——这已经是本周第三次因为事件冒泡导致的交互灾难了。

作为前端开发,我们每天都在和用户交互打交道。但你是否也曾遇到过这样的情况:点击一个子元素,父元素的事件也跟着触发;明明阻止了表单提交,却还是跳转到了新页面;写了e.preventDefault()却发现毫无作用,控制台还报错e is undefined

别以为事件冒泡和默认行为只是“点一下触发多个事件”这么简单。当产品经理拿着原型图问“为什么点击弹窗里的关闭按钮,背景层也跟着消失了”时,你才发现自己根本没处理事件冒泡;当用户投诉“输入框按回车会刷新页面”时,你才意识到忘了阻止表单的默认提交行为。

这篇文章不会干巴巴地讲stopPropagation()preventDefault()的语法,而是用前端人都懂的大白话,告诉你为什么同样是处理点击事件,有人能精准控制触发范围,有人却让事件像脱缰的野马四处乱窜;为什么别人的表单能乖乖等待验证完成再提交,你的表单却总是“自作主张”。就像硝酸甘油能缓解心绞痛一样,这篇指南能让你在面对混乱的事件交互时,保持清晰的逻辑,高效解决问题。

问题场景

场景1:“弹窗连环炸”的冒泡惨案

小周开发的电商详情页,有一个“加入购物车”的弹窗,弹窗里有“确定”按钮,弹窗外层有半透明的遮罩层。产品要求点击遮罩层时关闭弹窗,但点击弹窗内部(包括按钮)时不关闭。结果用户点击“确定”按钮后,不仅执行了加入购物车的逻辑,弹窗也跟着关闭了。

痛点:事件冒泡就像在水里扔石头,涟漪会从落点一直扩散到岸边。点击子元素时,事件会顺着DOM树向上传播,触发所有祖先元素的同名事件。就像你按了家里的灯开关,结果邻居家的灯也跟着亮了,这显然不是你想要的结果。

场景2:“表单私奔”的默认行为

小王做的登录页面,表单里有用户名和密码输入框。用户输入一半按了回车,表单直接提交跳转了,之前填的内容全没了。产品经理怒怼:“没填完怎么能提交?就不能等用户点登录按钮吗?”

痛点:浏览器的默认行为就像自带的“自动驾驶模式”,某些元素在特定操作下会自动执行预设动作——表单提交、链接跳转、右键菜单弹出……这些默认行为虽然方便,但在需要自定义交互时就会帮倒忙,就像你想手动开车,车却自己加速冲了出去。

场景3:“事件拦截失效”的调试噩梦

小李在代码里写了e.preventDefault()阻止链接跳转,结果点击链接还是跳走了。他反复检查拼写没错,最后才发现事件处理函数里的参数写成了event,但调用时用了e,导致eundefined。这种低级错误让他排查了整整一下午。

痛点:阻止事件的方法看似简单,却藏着不少坑——参数名不匹配、忘了传参、在事件捕获阶段调用无效……这些问题就像医生开对了药,却给病人吃错了剂量,不仅没效果,还可能引发副作用。

场景4:“第三方插件冲突”的连锁反应

小张在项目里用了一个日历插件,同时自己写了点击文档空白处关闭弹窗的逻辑。结果点击日历选择日期时,弹窗总是自动关闭。排查后发现,日历插件的点击事件冒泡到了文档,触发了关闭逻辑。

痛点:当页面引入多个库或插件时,事件冒泡可能引发不可预知的冲突。就像多个部门共用一个会议室,A部门刚要开会,B部门的人推门就进,整个工作节奏全被打乱了。

技术原理

事件流:DOM的“通讯网络”

浏览器处理事件的过程分为三个阶段,就像快递的运输流程:

  1. 捕获阶段:事件从window对象向下传播到目标元素的父级(类似快递从仓库发往片区集散点)
  2. 目标阶段:事件到达目标元素(类似快递送到收件人楼下)
  3. 冒泡阶段:事件从目标元素的父级向上传播回window对象(类似快递签收后,消息回传到仓库)

我们平时用addEventListener绑定的事件,默认在冒泡阶段触发。可以通过第三个参数useCapture(默认false)来切换到捕获阶段。

事件冒泡:为什么点击子元素会触发父元素事件?

当你点击一个元素时,浏览器会先触发该元素的事件处理函数,然后顺着DOM树向上,依次触发每个父元素的同名事件处理函数。这种传播机制就是事件冒泡(Bubbling)。

<div class="grandpa">
  <div class="father">
    <div class="son">点击我</div>
  </div>
</div>

点击son时,事件触发顺序是:son → father → grandpa → body → html → document → window

这种机制的设计初衷是方便事件委托(Event Delegation)——只需给父元素绑定一次事件,就能处理所有子元素的事件,减少内存占用。但在不需要这种传播时,就必须手动阻止。

阻止事件冒泡的两种方法

  1. 标准方法:event.stopPropagation()

    • 属于W3C标准,兼容所有现代浏览器(IE8及以下不支持)
    • 作用:阻止事件在冒泡阶段继续向上传播,但不会影响当前元素的其他事件处理函数
  2. IE专属方法:event.cancelBubble = true

    • 仅支持IE8及以下浏览器
    • 作用和stopPropagation()相同,现代项目中已很少使用,但了解它有助于理解兼容性处理

事件默认行为:浏览器的“自动响应”

浏览器为许多元素预设了默认行为:

  • <a>标签点击跳转
  • <form>表单提交
  • <button type="submit">点击提交表单
  • 文本框按回车触发表单提交
  • 右键点击弹出上下文菜单
  • 按F5刷新页面

这些行为是Web发展初期为了简化开发设计的,但在需要自定义交互时,就必须禁用它们。

阻止默认行为的三种方法

  1. 标准方法:event.preventDefault()

    • W3C标准,现代浏览器通用
    • 作用:取消事件的默认行为,但不会阻止事件冒泡
  2. return false(仅限特定场景)

    • 在DOM0级事件处理程序中(如onclick="return false"),相当于同时调用preventDefault()stopPropagation()
    • 在jQuery的事件处理函数中,return false也会同时阻止冒泡和默认行为
    • 注意:在原生addEventListener中,return false无效!
  3. IE专属方法:event.returnValue = false

    • 仅支持IE8及以下,功能同preventDefault()

事件对象:传递信息的“信使”

所有事件处理函数都会接收一个事件对象(Event Object),它包含了事件的详细信息:

  • type:事件类型(如clickkeydown
  • target:触发事件的原始元素(目标元素)
  • currentTarget:当前处理事件的元素(绑定事件的元素)
  • bubbles:事件是否会冒泡
  • cancelable:事件是否可以阻止默认行为

正确使用事件对象是阻止事件冒泡和默认行为的前提,很多新手出错都是因为没正确获取这个对象。

代码示例

阻止事件冒泡的代码示例

基础示例:阻止点击事件冒泡
<div id="grandpa" style="padding: 50px; background: red;">
  爷爷
  <div id="father" style="padding: 50px; background: green;">
    爸爸
    <div id="son" style="padding: 50px; background: blue;">
      儿子
    </div>
  </div>
</div>

<script>
// 给爷爷绑定点击事件
document.getElementById('grandpa').addEventListener('click', function(e) {
  console.log('爷爷被点击了');
});

// 给爸爸绑定点击事件
document.getElementById('father').addEventListener('click', function(e) {
  console.log('爸爸被点击了');
  // 在这里阻止冒泡,爸爸的事件触发后,不会再传播给爷爷
  e.stopPropagation(); // 关键代码:阻止事件继续向上冒泡
});

// 给儿子绑定点击事件
document.getElementById('son').addEventListener('click', function(e) {
  console.log('儿子被点击了');
  // 如果这里不阻止冒泡,事件会传播给爸爸
  // e.stopPropagation(); // 取消注释后,只会触发儿子的事件
});
</script>

执行结果

  • 点击“儿子”:输出“儿子被点击了” → “爸爸被点击了”(因为爸爸阻止了冒泡,爷爷不会触发)
  • 如果儿子也阻止冒泡:只输出“儿子被点击了”
兼容IE8的阻止冒泡写法
// 封装一个兼容各浏览器的阻止冒泡函数
function stopBubbling(e) {
  // 标准浏览器
  if (e && e.stopPropagation) {
    e.stopPropagation();
  } else {
    // IE8及以下
    window.event.cancelBubble = true;
  }
}

// 使用示例
document.getElementById('son').addEventListener('click', function(e) {
  // 处理点击逻辑
  console.log('处理儿子的点击事件');
  // 调用封装好的函数阻止冒泡
  stopBubbling(e || window.event); // 兼容IE的事件对象获取方式
});
事件委托中阻止冒泡的应用
<ul id="list">
  <li>项目1</li>
  <li>项目2</li>
  <li>项目3</li>
  <li class="special">特殊项目(点击不触发)</li>
</ul>

<script>
// 事件委托:给父元素ul绑定一次事件,处理所有li的点击
document.getElementById('list').addEventListener('click', function(e) {
  // e.target是实际点击的元素
  if (e.target.tagName === 'LI') {
    // 判断是否是特殊项目
    if (e.target.classList.contains('special')) {
      console.log('这是特殊项目,不执行操作');
      e.stopPropagation(); // 阻止冒泡(如果有上层元素监听click)
      return;
    }
    console.log('点击了项目:' + e.target.textContent);
  }
});

// 外层容器的点击事件
document.body.addEventListener('click', function() {
  console.log('页面空白处被点击了');
});
</script>

说明:点击普通li会执行操作并触发body的事件,点击特殊li则只输出提示且不触发body事件(因为阻止了冒泡)

阻止默认行为的代码示例

阻止链接跳转
<!-- 普通链接会跳转 -->
<a href="https://www.example.com" id="normalLink">普通链接(会跳转)</a>

<!-- 阻止跳转的链接 -->
<a href="https://www.example.com" id="preventLink">阻止跳转的链接</a>

<script>
// 给需要阻止跳转的链接绑定事件
document.getElementById('preventLink').addEventListener('click', function(e) {
  e.preventDefault(); // 阻止默认跳转行为
  console.log('链接被点击了,但不会跳转');
  
  // 可以在这里添加自定义逻辑
  setTimeout(() => {
    console.log('3秒后再跳转');
    window.location.href = this.href; // 手动跳转
  }, 3000);
});
</script>
阻止表单提交
<form id="myForm" action="/submit" method="get">
  <input type="text" name="username" placeholder="用户名">
  <button type="submit" id="submitBtn">提交</button>
</form>

<script>
// 获取表单元素
const form = document.getElementById('myForm');

// 给表单绑定提交事件
form.addEventListener('submit', function(e) {
  // 获取输入框的值
  const username = this.querySelector('input[name="username"]').value;
  
  // 简单验证
  if (!username.trim()) {
    alert('请输入用户名');
    e.preventDefault(); // 验证失败,阻止提交
    return;
  }
  
  // 验证通过,可以提交(不阻止默认行为)
  console.log('表单即将提交');
});

// 也可以给提交按钮绑定点击事件来阻止
document.getElementById('submitBtn').addEventListener('click', function(e) {
  const username = form.querySelector('input[name="username"]').value;
  if (!username.trim()) {
    alert('请输入用户名');
    e.preventDefault(); // 阻止按钮的默认提交行为
  }
});
</script>
阻止右键菜单(上下文菜单)
<div id="noRightClick" style="width: 200px; height: 200px; background: yellow;">
  这里不能右键点击
</div>

<script>
// 监听contextmenu事件(右键菜单事件)
document.getElementById('noRightClick').addEventListener('contextmenu', function(e) {
  e.preventDefault(); // 阻止默认右键菜单
  alert('别右键点击我,有话好好说');
});
</script>
阻止回车提交表单
<form id="searchForm">
  <input type="text" name="keyword" placeholder="搜索关键词">
  <button type="button" id="searchBtn">搜索</button>
</form>

<script>
const form = document.getElementById('searchForm');
const input = form.querySelector('input');

// 监听输入框的键盘事件
input.addEventListener('keydown', function(e) {
  // 判断是否按的是回车键(keyCode为13)
  if (e.keyCode === 13) {
    e.preventDefault(); // 阻止回车触发的默认提交
    console.log('按了回车,执行自定义搜索逻辑');
    // 调用搜索函数
    search();
  }
});

// 搜索按钮点击事件
document.getElementById('searchBtn').addEventListener('click', search);

// 搜索逻辑
function search() {
  const keyword = input.value.trim();
  if (keyword) {
    console.log('搜索:' + keyword);
    // 这里写实际的搜索逻辑
  } else {
    alert('请输入搜索关键词');
  }
}
</script>

同时阻止冒泡和默认行为的示例

<a href="https://example.com" id="link" style="display: block; padding: 20px; background: pink;">
  <span id="span">点击我</span>
</a>

<script>
// 给span绑定点击事件
document.getElementById('span').addEventListener('click', function(e) {
  e.stopPropagation(); // 阻止冒泡到a标签
  e.preventDefault(); // 阻止a标签的默认跳转(虽然这里是span,但事件对象可以传递)
  console.log('span被点击,既不冒泡也不跳转');
});

// 给a标签绑定点击事件
document.getElementById('link').addEventListener('click', function() {
  console.log('a标签被点击(如果span没阻止冒泡,这里会触发)');
});

// 给body绑定点击事件
document.body.addEventListener('click', function() {
  console.log('body被点击(如果没阻止冒泡,这里会触发)');
});
</script>

return false的特殊用法

<!-- 在DOM0级事件中,return false会同时阻止冒泡和默认行为 -->
<a href="https://example.com" onclick="console.log('点击了链接'); return false;">
  点我不会跳转,也不会冒泡
</a>

<script>
// 在原生addEventListener中,return false无效
const link = document.createElement('a');
link.href = 'https://example.com';
link.textContent = '原生绑定的链接';
link.addEventListener('click', function() {
  console.log('原生绑定的点击事件');
  return false; // 这里的return false没用,仍然会跳转
});
document.body.appendChild(link);

// 在jQuery中,return false会同时阻止冒泡和默认行为
// 需要引入jQuery库
// $('#jqueryLink').click(function() {
//   console.log('jQuery绑定的点击事件');
//   return false; // 有效:不跳转也不冒泡
// });
</script>

对比效果

操作类型方法作用是否阻止冒泡是否阻止默认行为兼容性适用场景
阻止冒泡e.stopPropagation()停止事件向上传播IE9+及现代浏览器只需要阻止事件扩散,不影响默认行为
阻止冒泡e.cancelBubble = true停止事件向上传播IE8及以下兼容古老IE浏览器
阻止默认行为e.preventDefault()取消浏览器预设动作IE9+及现代浏览器只需要禁用默认行为,允许事件冒泡
阻止默认行为e.returnValue = false取消浏览器预设动作IE8及以下兼容古老IE浏览器
同时阻止return false(DOM0级)停止传播并取消默认所有浏览器简单场景下同时需要两种效果
同时阻止return false(jQuery)停止传播并取消默认引入jQuery的项目jQuery环境下的快捷写法
同时阻止手动组合先阻止冒泡再阻止默认所有浏览器需要精确控制的复杂场景

面试题回答方法

面试题:如何在JavaScript中阻止事件冒泡和事件默认行为?它们有什么区别?

正常回答方法

在JavaScript中,阻止事件冒泡和阻止事件默认行为是两种不同的操作,用于控制事件的传播和浏览器的预设行为。

阻止事件冒泡的方法有两种:

  1. 标准方法:使用event.stopPropagation(),该方法会阻止事件在冒泡阶段继续向上传播,但不会影响事件的默认行为。适用于IE9及以上现代浏览器。
  2. IE兼容方法:设置event.cancelBubble = true,功能与stopPropagation()相同,主要用于IE8及以下浏览器。

阻止事件默认行为的方法有三种:

  1. 标准方法:使用event.preventDefault(),该方法会取消浏览器对当前事件的预设动作(如表单提交、链接跳转),但不会影响事件冒泡。
  2. IE兼容方法:设置event.returnValue = false,功能与preventDefault()相同,用于IE8及以下浏览器。
  3. return false:在DOM0级事件处理程序(如onclick属性)中,return false会同时阻止事件冒泡和默认行为;在jQuery事件处理函数中也有相同效果,但在原生addEventListener中无效。

两者的主要区别在于:

  • 作用对象不同:事件冒泡针对事件的传播过程,默认行为针对浏览器的预设动作。
  • 目的不同:阻止冒泡是为了避免事件触发父元素的同名事件,阻止默认行为是为了禁用浏览器的自带功能,实现自定义交互。
  • 方法独立性:阻止冒泡不会影响默认行为,阻止默认行为也不会影响事件冒泡,可根据需求单独或同时使用。

在实际开发中,应根据浏览器兼容性和具体需求选择合适的方法,现代项目推荐使用标准方法,并通过特性检测实现兼容处理。

大白话回答方法

说白了,阻止事件冒泡和阻止默认行为就是两件事:

阻止事件冒泡就像“隔音处理”。比如你在卧室听歌,不想让客厅的人听到,就关上门。点击网页里的按钮时,事件本来会像声音一样传到父元素、爷爷元素,用stopPropagation()就能把这个“声音”挡住,让上层元素听不见。

阻止默认行为就像“取消自动操作”。浏览器有很多自带的“强迫症”:点链接就跳转、按回车就提交表单、右键就出菜单……这些行为有时候很烦人。用preventDefault()就能让浏览器“别乱动”,听我们的指挥。

具体怎么用呢?简单说:

  • 想不让事件往上跑,就用e.stopPropagation()
  • 想不让浏览器瞎自动,就用e.preventDefault()
  • 老IE浏览器比较特殊,得用e.cancelBubble = truee.returnValue = false
  • 还有个偷懒的return false,在老式写法里能同时搞定两件事,但在现代写法里经常不好使,所以别乱用

举个例子:点击弹窗里的按钮,既要执行按钮的功能,又不想让弹窗关闭(阻止冒泡),这时候用stopPropagation();点击表单的提交按钮,想先验证内容再决定是否提交,这时候用preventDefault()拦住默认提交,等验证通过了再手动提交。

记住一点:这俩操作互不影响,想同时用就一起写,想单独用就分开写,看你具体要解决啥问题。

总结

事件冒泡和默认行为是JavaScript事件处理中的两个核心概念,理解并掌握它们的控制方法,是写出流畅交互的前提。

事件冒泡就像水中涟漪,会从触发点向上扩散,stopPropagation()能有效阻止这种扩散,避免父元素的事件被误触发。这在处理嵌套元素的交互(如弹窗、下拉菜单)时特别重要,能防止“点A触发B”的乌龙事件。

浏览器的默认行为是把双刃剑,方便了基础交互却限制了自定义需求。preventDefault()就像一把“总开关”,能禁用这些预设动作,让我们自由实现表单验证、自定义链接跳转等功能。

实际开发中要注意:

  • 事件对象是基础,必须正确获取和传递
  • 现代项目优先用stopPropagation()preventDefault()
  • return false有坑,非必要不用
  • 处理第三方插件时,注意事件冒泡可能引发的冲突

记住这些要点,面对复杂的交互场景时,你就能像经验丰富的交通指挥家,让各种事件按规则有序进行,而不是变成一团乱麻。

扩展思考

扩展思考1:事件委托和事件冒泡是什么关系?

事件委托(Event Delegation)是一种利用事件冒泡机制实现的编程模式,两者是“技术原理”和“应用方式”的关系。

具体来说,事件委托通过将子元素的事件处理函数绑定到父元素上,利用事件冒泡的特性,当子元素触发事件时,事件会冒泡到父元素,由父元素的处理函数统一处理。

优点包括:

  • 减少事件绑定次数,节省内存(尤其是列表等动态元素)
  • 新增子元素自动拥有事件处理,无需重新绑定
  • 简化代码结构,便于维护

实现示例:

// 给ul绑定一次事件,处理所有li的点击
document.querySelector('ul').addEventListener('click', function(e) {
  // 通过e.target判断是否点击了li
  if (e.target.tagName === 'LI') {
    console.log('点击了li:' + e.target.textContent);
  }
});

这里的关键就是事件冒泡——li的点击事件能冒泡到ul,否则事件委托无法实现。但要注意,如果在子元素中阻止了冒泡(e.stopPropagation()),事件委托就会失效。

扩展思考2:stopPropagation()stopImmediatePropagation()有什么区别?

两者都能阻止事件冒泡,但stopImmediatePropagation()更“狠”:

  • stopPropagation():只阻止事件向上冒泡,不影响当前元素的其他事件处理函数
  • stopImmediatePropagation():不仅阻止冒泡,还会阻止当前元素后续绑定的同类型事件处理函数

示例:

const btn = document.getElementById('btn');

// 第一个点击事件处理函数
btn.addEventListener('click', function(e) {
  console.log('第一个处理函数');
  // e.stopPropagation(); // 只阻止冒泡,第二个处理函数会执行
  e.stopImmediatePropagation(); // 阻止冒泡+阻止后续处理函数
});

// 第二个点击事件处理函数
btn.addEventListener('click', function() {
  console.log('第二个处理函数'); // 如果用了stopImmediatePropagation,这里不会执行
});

// 父元素的点击事件
document.body.addEventListener('click', function() {
  console.log('body的处理函数'); // 如果阻止了冒泡,这里不会执行
});

使用场景:当需要严格控制事件处理顺序,或防止其他脚本干扰时,用stopImmediatePropagation();普通阻止冒泡用stopPropagation()即可。

扩展思考3:为什么有时候preventDefault()会失效?

preventDefault()失效通常有以下几种原因:

  1. 事件不可取消:某些事件的cancelable属性为false(不可取消),如loadscroll事件,调用preventDefault()无效。
window.addEventListener('scroll', function(e) {
  e.preventDefault(); // 无效,scroll事件不可取消
});
  1. 调用时机错误:在事件捕获阶段调用preventDefault()可能对某些冒泡阶段的默认行为无效,应在目标阶段或冒泡阶段调用。

  2. 事件对象错误:未正确传递事件对象,或参数名不匹配(如函数参数用e,但实际传的是event)。

// 错误示例:参数名不匹配
btn.addEventListener('click', function(event) {
  e.preventDefault(); // 报错:e is undefined
});
  1. 第三方库冲突:某些库可能会重写事件处理机制,导致preventDefault()被覆盖或失效。

解决方法:

  • event.cancelable检查事件是否可取消
  • 确保事件对象正确传递和引用
  • 在事件处理函数开头调用preventDefault()
  • 必要时使用return false(仅限DOM0级事件)

扩展思考4:移动端触摸事件的冒泡和默认行为有哪些特殊之处?

移动端的touch事件(touchstarttouchmovetouchend)也存在冒泡和默认行为,但有特殊之处:

  1. 触摸事件的冒泡

    • 和点击事件一样会冒泡,可用stopPropagation()阻止
    • 但触摸事件的传播速度更快,可能引发更复杂的交互冲突(如滑动和点击的冲突)
  2. 需要特别处理的默认行为

    • 页面滚动(touchmove会触发)
    • 缩放(双指触摸)
    • 长按选中文字
    • 链接和表单元素的默认行为
  3. 常用解决方案

    • 阻止页面滚动:在touchmove中调用preventDefault()
    document.addEventListener('touchmove', function(e) {
      e.preventDefault(); // 阻止页面滚动
    }, { passive: false }); // 注意passive选项
    
    • 处理滑动冲突:通过触摸位置计算判断是滑动还是点击,再决定是否阻止冒泡

    • passive选项:现代浏览器中,touchmovewheel事件默认启用passive: true,此时preventDefault()会失效并报警告,需显式设置passive: false

  4. 300ms延迟问题:移动端点击事件有300ms延迟(为判断双击缩放),解决方法包括:

    • 使用<meta name="viewport" content="width=device-width">
    • touch事件替代click
    • 使用FastClick

移动端事件处理更复杂,需要平衡用户体验和自定义需求,过度阻止默认行为可能导致页面失去基本交互能力(如无法滚动)。

结尾

事件冒泡和默认行为就像前端开发中的“隐形之手”,看不见摸不着,却时刻影响着用户交互。掌握了stopPropagation()preventDefault()这两个“遥控器”,你就能从被动应对变成主动掌控。

回想一下,你是不是也遇到过这些场景:

  • 点击弹窗按钮却触发了关闭逻辑
  • 下拉菜单展开时,点击其他地方没反应
  • 移动端滑动列表时,页面总是跟着滚动

这些问题的根源都是没处理好事件的传播和默认行为。现在再遇到类似问题,你应该能快速定位原因,用今天学到的方法轻松解决。

最后送大家一句口诀:“冒泡传播像涟漪,stopPropagation来隔离;默认行为别任性,preventDefault管到底;事件对象要抓牢,参数名称别错记;兼容处理不能少,交互流畅才满意。” 希望这句口诀能帮你记住今天的知识点!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端布洛芬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值