You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React项目document.readystatechange事件未触发问题求助

问题排查与解决方案

核心原因

你的代码仅监听readystatechange事件,但当组件挂载时,文档可能已经处于complete状态——这个事件只有在文档状态从loading→interactive→complete发生变化时才会触发,若组件挂载时机晚于文档完成时机,事件回调就不会被执行。

旧电脑上正常是因为组件挂载比文档完成早,能捕获到状态变化;新电脑可能因浏览器缓存、本地性能更优,文档提前加载完成,组件挂载时状态已经是complete,所以事件从未触发。另外你的useEffect没有设置依赖数组,会导致组件每次渲染都重复注册/移除事件,属于不必要的性能损耗。

修复后的代码

function useElementDimension(elementId: string) {
  const [dimensions, setDimensions] = useState({
      height: 0,
      width: 0
  });

  useEffect(() => {
    function updateDimensions() {
      const stage = document.getElementById(elementId);
      if(stage === null) return;
      setDimensions({width: stage.clientWidth, height: stage.clientHeight});
    }

    // 先检查当前文档状态,已完成则直接更新尺寸
    if(document.readyState === "complete") {
      updateDimensions();
    }

    // 监听文档状态变化和窗口resize(适配flexbox动态尺寸变化)
    document.addEventListener('readystatechange', updateDimensions);
    window.addEventListener('resize', updateDimensions);

    return () => {
      document.removeEventListener('readystatechange', updateDimensions);
      window.removeEventListener('resize', updateDimensions);
    };
  }, [elementId]); // 添加依赖数组,仅在elementId变化时重新执行

  return dimensions;
}

额外说明

  1. 将原onLoaded重命名为updateDimensions,更贴合功能定位:不仅在文档就绪时执行,后续窗口resize时也能更新尺寸,适配flexbox布局的动态变化。
  2. 新增窗口resize事件监听,因为flexbox元素尺寸可能随窗口大小改变,仅在文档就绪时获取一次尺寸无法覆盖所有场景。
  3. 给useEffect添加[elementId]依赖,确保只有目标元素ID变化时才重新绑定事件,避免无效重复执行。

内容的提问来源于stack exchange,提问作者Ivan Lo Greco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 13:35:23