JavaScript事件按捕获→目标→冒泡三阶段运行;stopPropagation()阻止冒泡,preventDefault()取消默认行为;passive和once选项可优化高频事件性能。
JavaScript 事件基于“捕获 → 目标 → 冒泡”三阶段模型运行。当你点击一个按钮,事件先从 document 向下传递(捕获),到达目标
元素(比如按钮本身),再向上逐级回传(冒泡)到父、祖父等元素。默认行为则由浏览器自动触发(如点击链接跳转、表单提交刷新页面)。要控制这些流程,关键靠 event.stopPropagation() 和 event.preventDefault()。
冒泡意味着子元素的事件会“透上去”,触发所有祖先元素上绑定的同类型事件监听器。如果你只想让按钮自己处理点击,不想让包裹它的 div 或 body 也执行对应逻辑,就需要阻止冒泡。
event.stopPropagation() 可立即中断冒泡路径,后续祖先元素的事件监听器不会被触发once: true)event.stopImmediatePropagation(),它还能阻止当前元素上其他未执行的监听器很多元素有内置行为—— 点击跳转、 提交刷新、 点击切换选中状态。这些不是 JS 添加的,而是浏览器原生逻辑。
event.preventDefault() 即可取消该默认动作,但事件仍会继续冒泡(除非额外调用 stopPropagation)submit 事件中调用它,否则页面会刷新Enter 触发搜索),也常需 preventDefault() 防止意外换行或提交假设你有一个点击展开的菜单,点击菜单项后关闭,但点击外部区域也要关闭。如果没处理好冒泡和默认行为,就容易出现点菜单项时菜单闪闭、或点击链接跳走了。
preventDefault() 防止链接跳转,再用 toggleMenu()
stopPropagation(),避免事件冒泡到 document 的隐藏监听器对于滚动、触摸等高频事件,可以加选项优化性能:
{ passive: true } 告诉浏览器你不会调用 preventDefault()(比如只是读取滚动位置),让浏览器更流畅地处理原生滚动{ once: true } 让监听器只执行一次,适合初始化或一次性操作,省去手动 removeEventListener
element.addEventListener('click', handler, { once: true })