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

React中iframe加载时显示加载器(onLoad事件未生效)

解决React+Tailwind中Iframe onLoad事件不触发导致加载界面无法关闭的问题

问题分析

你当前的实现用条件渲染切换加载状态和iframe,但可能遇到以下几个问题:

  • 缓存导致onLoad不触发:浏览器缓存iframe内容时,再次加载不会触发onLoad事件,加载状态一直保持true。
  • Calendly嵌入的特殊性:Calendly的嵌入内容是动态加载的,原生iframe的onLoad事件可能在Calendly实际内容渲染完成前就触发,或者它的加载逻辑不依赖原生iframe的onLoad。
  • 条件渲染的局限性:只有当isIframeLoading为false时才渲染iframe,若第一次加载时onLoad未触发,iframe不会被渲染,自然无法后续触发事件。

解决方案

方案1:始终渲染iframe,用加载层覆盖(最直接修复)

修改渲染逻辑,不管加载状态都渲染iframe,加载界面作为绝对定位的overlay覆盖在iframe上方,确保iframe始终存在以触发onLoad:

const [isIframeLoading, setIsIframeLoading] = useState(true);

return (
  <div className="flex justify-center items-center w-full xm:w-3/4 h-full relative">
    {/* 始终渲染iframe */}
    <iframe 
      className="w-full h-full min-h-[1250px] calendly:min-h-[750px] border-0 box-border"
      src={calendlyEmbed}
      onLoad={() => setIsIframeLoading(false)}
      title='Select a Date & Time - Calendly'
    ></iframe>
    {/* 加载状态时显示覆盖层 */}
    {isIframeLoading && (
      <div className="absolute inset-0 h-full w-full bg-ac-gray2 brightness-75 rounded-lg animate-pulse"></div>
    )}
  </div>
);

方案2:监听Calendly官方加载事件(适配Calendly场景)

Calendly提供官方API监听嵌入内容的加载完成事件,比原生iframe onLoad更可靠:

  1. 在项目中引入Calendly脚本(可放在public/index.html或组件内动态引入):
<script type="text/javascript" src="https://assets.calendly.com/assets/external/widget.js"></script>
  1. 在组件中监听calendly.loaded事件:
import { useEffect, useState } from 'react';

const CalendlyEmbed = () => {
  const [isIframeLoading, setIsIframeLoading] = useState(true);

  useEffect(() => {
    const handleLoaded = () => setIsIframeLoading(false);
    window.addEventListener('calendly.loaded', handleLoaded);
    return () => window.removeEventListener('calendly.loaded', handleLoaded);
  }, []);

  return (
    <div className="flex justify-center items-center w-full xm:w-3/4 h-full relative">
      <iframe 
        className="w-full h-full min-h-[1250px] calendly:min-h-[750px] border-0 box-border"
        src={calendlyEmbed}
        title='Select a Date & Time - Calendly'
      ></iframe>
      {isIframeLoading && (
        <div className="absolute inset-0 bg-ac-gray2 brightness-75 rounded-lg animate-pulse"></div>
      )}
    </div>
  );
};

export default CalendlyEmbed;

方案3:避免缓存触发onLoad

如果是浏览器缓存导致onLoad不触发,可给iframe的src添加随机参数强制加载新内容:

const cacheBustedSrc = `${calendlyEmbed}?t=${Date.now()}`;

// 将cacheBustedSrc作为iframe的src属性使用

关键说明

  • 方案1解决了条件渲染导致iframe未初始化的问题,确保onLoad能被触发;
  • 方案2针对Calendly场景,利用官方事件准确捕获内容加载完成时机;
  • 方案3适配缓存导致的重复加载不触发onLoad的情况,但会增加加载时间,按需选择。

内容的提问来源于stack exchange,提问作者oussamaZAAM

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 19:39:51