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

Next.js模态框滚动关闭问题:仅在container区域滚动时关闭模态框

问题描述

在Next.js应用中实现了一个模态框,点击容器外部(container或inner元素)时会关闭,但需要实现:当用户在container元素中滚动时自动关闭模态框,而在inner元素或白色内容区滚动时不关闭。之前尝试监听window.scroll会导致所有滚动操作都关闭模态框,不符合需求。

现有代码如下:

Page.js

const [showTypeModal, setShowTypeModal] = useState(false);

const handleTypeModalClose = () => setShowTypeModal(false);

<TypeModal onClose={handleTypeModalClose} visible={showTypeModal} />

TypeModal.js

const handleOnClose = (e) => {
    if (e.target.id === "container" || e.target.id === "inner") onClose();
  };
  if (!visible) return null;

return (
    <div
      id="container"
      onClick={handleOnClose}
      className="fixed top-44 left-0 right-0 bottom-0 bg-gray-400 bg-opacity-30 backdrop-blur-sm hidden md:flex"
    >
      <div id="inner" className="w-3/6" onClick={handleOnClose} />
      <div className="h-[60%] w-1/5 bg-white drop-shadow-md rounded-3xl flex flex-col justify-evenly items-start overflow-auto">
        {homeType.map((type) => {
          return (
            <div
              key={type.id}
              onClick={() => dispatch(addType(type.name))}
              className="hover:bg-[#f0fcfb] cursor-pointer w-full h-14 pl-10  last:rounded-b-3xl first:rounded-t-3xl flex items-center"
            >
              {type.name}
            </div>
          );
        })}
      </div>
    </div>
  );

解决方案

不需要全局监听window的滚动事件,通过事件冒泡控制实现精准触发:

  1. 给container元素添加scroll事件,触发关闭逻辑
  2. 给白色内容区添加onScroll事件,阻止事件冒泡,避免滚动内容区时触发container的滚动事件

修改后的TypeModal.js代码:

const handleOnClose = (e) => {
  if (e.target.id === "container" || e.target.id === "inner") onClose();
};

if (!visible) return null;

return (
  <div
    id="container"
    onClick={handleOnClose}
    onScroll={onClose} {/* 添加container滚动关闭逻辑 */}
    className="fixed top-44 left-0 right-0 bottom-0 bg-gray-400 bg-opacity-30 backdrop-blur-sm hidden md:flex"
  >
    <div id="inner" className="w-3/6" onClick={handleOnClose} />
    {/* 给内容区添加stopPropagation阻止滚动事件冒泡 */}
    <div 
      className="h-[60%] w-1/5 bg-white drop-shadow-md rounded-3xl flex flex-col justify-evenly items-start overflow-auto"
      onScroll={(e) => e.stopPropagation()}
    >
      {homeType.map((type) => {
        return (
          <div
            key={type.id}
            onClick={() => dispatch(addType(type.name))}
            className="hover:bg-[#f0fcfb] cursor-pointer w-full h-14 pl-10  last:rounded-b-3xl first:rounded-t-3xl flex items-center"
          >
            {type.name}
          </div>
        );
      })}
    </div>
  </div>
);

原理说明

  • 滚动container(背景区域)时,触发其scroll事件,直接调用onClose关闭模态框
  • 滚动白色内容区时,e.stopPropagation()阻止事件冒泡到container,因此不会触发关闭逻辑
  • 保留原有的点击关闭逻辑,确保交互一致性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 11:20:37