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

如何让NextUI模态框内的Iframe无滚动,由模态框处理滚动?

问题:NextUI模态框内嵌Iframe高度自适应,由模态框处理滚动

我在NextUI模态框中嵌入了一个Iframe,由于Iframe内的页面高度各不相同,无法为其设置固定高度。当我将高度设为100%时,Iframe仅显示150px高度且出现内部滚动。请问如何设置高度,让Iframe无滚动,由设置了scrollBehavior:outside的NextUI模态框来处理滚动?

Iframe组件原代码:

const IframeComponent = () => {
  return <iframe title="wheel" url="XXXX" className="h-full w-full rounded-[30px]" />
}

export default IframeComponent

模态框组件原代码:

import { Modal, ModalBody, ModalContent, ModalProps, useDisclosure } from "@nextui-org/react"
import Image from "next/image"
import { useEffect, useState } from "react"
import IframeComponent from "./Iframe"

const IframeWrapper = () => {
  const { isOpen, onOpen, onClose, onOpenChange } = useDisclosure()
  const [scrollBehavior, _setScrollBehavior] = useState<ModalProps["scrollBehavior"]>("outside")

  // Open the modal on load.
  // Does the modal need to open on each load?
  useEffect(() => {
    onOpen()
  }, [onOpen])

  return (
    <>
      <Modal
        isOpen={isOpen}
        onOpenChange={onOpenChange}
        size="5xl"
        placement="center"
        hideCloseButton={true}
        radius="lg"
        scrollBehavior={scrollBehavior}
        className="w-[90vw]"
      >
        <ModalContent>
          <>
            <ModalBody className="p-0">
              <button
                onClick={onClose}
                className="absolute right-4 top-3 select-none appearance-none rounded-full p-2 text-foreground-500 outline-none tap-highlight-transparent data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-offset-2 data-[focus-visible=true]:outline-focus rtl:left-1 rtl:right-[unset] lg:right-10 lg:top-7"
              >
                <Image
                  src="/icons/closeModal.svg"
                  alt="close button"
                  width={0}
                  height={0}
                  className="h-8 w-8 lg:h-16 lg:w-16"
                />
              </button>
              <IframeComponent />
            </ModalBody>
          </>
        </ModalContent>
      </Modal>
    </>
  )
}
export default IframeWrapper

解决方案

要实现Iframe高度自适应内容、禁用内部滚动,让模态框处理滚动,需要从以下几个方面调整:

1. 调整Iframe组件配置

  • 修正Iframe的src属性(原代码误写为url)
  • 禁用Iframe内部滚动,添加scrolling="no"属性
  • 监听Iframe加载完成事件,动态设置其高度为内容实际高度

修改后的Iframe组件:

import { useEffect, useRef } from "react";

const IframeComponent = () => {
  const iframeRef = useRef<HTMLIFrameElement>(null);

  useEffect(() => {
    const iframe = iframeRef.current;
    if (!iframe) return;

    // 监听Iframe加载完成,获取内容高度
    const handleLoad = () => {
      try {
        // 同源页面直接获取内容高度
        const contentHeight = iframe.contentWindow?.document.body.scrollHeight || 0;
        iframe.style.height = `${contentHeight}px`;
      } catch (e) {
        // 跨域页面需子页面配合发送高度数据
        window.addEventListener('message', (event) => {
          if (event.data?.height) {
            iframe.style.height = `${event.data.height}px`;
          }
        });
      }
    };

    iframe.addEventListener("load", handleLoad);
    return () => iframe.removeEventListener("load", handleLoad);
  }, []);

  return (
    <iframe
      ref={iframeRef}
      title="wheel"
      src="XXXX"
      className="w-full rounded-[30px]"
      scrolling="no"
      style={{ border: "none" }}
    />
  );
};

export default IframeComponent;

2. 调整模态框及ModalBody样式

  • 确保ModalBody不设置固定高度,添加min-h-0类移除默认最小高度限制
  • 保持模态框scrollBehavior="outside"配置,让模态框容器处理滚动

修改后的模态框关键部分:

<Modal
  isOpen={isOpen}
  onOpenChange={onOpenChange}
  size="5xl"
  placement="center"
  hideCloseButton={true}
  radius="lg"
  scrollBehavior="outside"
  className="w-[90vw]"
>
  <ModalContent>
    <>
      <ModalBody className="p-0 min-h-0">
        <button
          onClick={onClose}
          className="absolute right-4 top-3 select-none appearance-none rounded-full p-2 text-foreground-500 outline-none tap-highlight-transparent data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-offset-2 data-[focus-visible=true]:outline-focus rtl:left-1 rtl:right-[unset] lg:right-10 lg:top-7"
        >
          <Image
            src="/icons/closeModal.svg"
            alt="close button"
            width={0}
            height={0}
            className="h-8 w-8 lg:h-16 lg:w-16"
          />
        </button>
        <IframeComponent />
      </ModalBody>
    </>
  </ModalContent>
</Modal>

3. 跨域场景补充

如果Iframe加载跨域页面,直接获取内容高度会触发安全限制,需要子页面配合发送高度信息:
在子页面代码中添加:

// 页面加载或内容变化时发送高度
const sendHeight = () => {
  const height = document.body.scrollHeight;
  window.parent.postMessage({ height }, '*'); // 建议替换*为目标域名提升安全性
};

window.addEventListener('load', sendHeight);
// 若内容动态加载,需额外监听内容变化触发sendHeight

内容的提问来源于stack exchange,提问作者Rom-888

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 07:18:25