Yasin

Yasin

dom0事件和dom2事件的区别

DOM0 级事件

写法:

  • HTML 内联:<button onclick="fn()">
  • JS 属性赋值:el.onclick = fn

特点:

  • 同一个事件类型只能绑定一个处理函数(后面的会覆盖前面的)。
  • 简单直接,适合非常小的 demo 或临时逻辑。
  • 不够灵活,维护性一般。

DOM2 级事件

写法:

  • el.addEventListener('click', fn, options)
  • el.removeEventListener('click', fn, options)

特点:

  • 同一个事件可绑定多个处理函数,不互相覆盖。
  • 支持捕获/冒泡、oncepassive 等配置。
  • 可精确解绑,工程化更友好。

分别用在什么时候?

  • DOM0:快速测试、极简页面、一次性脚本。
  • DOM2:正式项目、组件化开发、需要多人协作和可维护性时。

一般推荐哪种?

推荐 DOM2(addEventListener
原因:更标准、更灵活、可维护性更好,是现代前端默认选择。

  1. 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:需要精确解绑,避免内存泄漏 尤其组件卸载时清理监听。

  1. 在 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。