dom0事件和dom2事件的区别
DOM0 级事件
写法:
- HTML 内联:
<button onclick="fn()"> - JS 属性赋值:
el.onclick = fn
特点:
- 同一个事件类型只能绑定一个处理函数(后面的会覆盖前面的)。
- 简单直接,适合非常小的 demo 或临时逻辑。
- 不够灵活,维护性一般。
DOM2 级事件
写法:
el.addEventListener('click', fn, options)el.removeEventListener('click', fn, options)
特点:
- 同一个事件可绑定多个处理函数,不互相覆盖。
- 支持捕获/冒泡、
once、passive等配置。 - 可精确解绑,工程化更友好。
分别用在什么时候?
- DOM0:快速测试、极简页面、一次性脚本。
- DOM2:正式项目、组件化开发、需要多人协作和可维护性时。
一般推荐哪种?
推荐 DOM2(addEventListener)。
原因:更标准、更灵活、可维护性更好,是现代前端默认选择。
- React JSX 里的 onClick={xxx},不属于传统 DOM0 写法 它看起来像 DOM0(都是 onxxx),但本质不是给真实 DOM 节点做 el.onclick = fn。 React 会把它注册到自己的事件系统(Synthetic Event),底层依赖浏览器的 addEventListener(DOM2 思路)做统一监听和分发。
所以在分类上:
不是原生 DOM0 更接近 DOM2 的机制(由 React 封装)2) DOM2(addEventListener)典型使用场景 场景 A:一个事件需要多个监听器 DOM0 会覆盖,DOM2 可并存。
场景 B:需要捕获阶段、冒泡控制 比如父层先拦截(capture)再到子元素。
场景 C:需要 once / passive / signal once: true:只执行一次 passive: true:提升滚动性能(如 touchmove、wheel) AbortController:集中取消监听 场景 D:给 window / document / 第三方 DOM 绑事件 例如:
resize scroll visibilitychange 键盘全局快捷键 非 React 管理的 DOM(地图、图表库生成的节点) 场景 E:需要精确解绑,避免内存泄漏 尤其组件卸载时清理监听。
- 在 React 里什么时候手写 DOM2? 在 JSX 上绑定组件内点击,直接 onClick 就行(推荐 React 方式)。 但遇到全局对象或非 React 节点时,用 useEffect + addEventListener/removeEventListener:
import { useEffect } from 'react';export default function Demo() { useEffect(() => { const onResize = () => { console.log('window resized'); }; window.addEventListener('resize', onResize, { passive: true }); return () => { window.removeEventListener('resize', onResize); }; }, []); return <button onClick={() => console.log('react click')}>Click;} 一句话总结:React 的 onClick 是 React 事件系统,不是原生 DOM0;工程实践里原生事件处理优先 DOM2。
