当前位置:首页 > React

react popover实现

2026-01-26 16:57:12React

使用 React Portals 实现 Popover

React Portals 提供了一种将子节点渲染到父组件 DOM 层次结构之外的 DOM 节点的方式,适合实现弹出层。

import React, { useState, useRef } from 'react';
import ReactDOM from 'react-dom';

function Popover({ content, children }) {
  const [isOpen, setIsOpen] = useState(false);
  const triggerRef = useRef(null);

  const handleClick = () => setIsOpen(!isOpen);

  return (
    <>
      <span ref={triggerRef} onClick={handleClick}>
        {children}
      </span>
      {isOpen &&
        ReactDOM.createPortal(
          <div className="popover">
            <div className="popover-content">{content}</div>
          </div>,
          document.body
        )}
    </>
  );
}

使用 CSS 定位 Popover

通过获取触发元素的位置信息,可以精确控制 Popover 的显示位置。

function Popover({ content, children }) {
  const [isOpen, setIsOpen] = useState(false);
  const [position, setPosition] = useState({ top: 0, left: 0 });
  const triggerRef = useRef(null);

  const handleClick = () => {
    if (triggerRef.current) {
      const rect = triggerRef.current.getBoundingClientRect();
      setPosition({
        top: rect.bottom + window.scrollY,
        left: rect.left + window.scrollX
      });
    }
    setIsOpen(!isOpen);
  };

  return (
    <>
      <span ref={triggerRef} onClick={handleClick}>
        {children}
      </span>
      {isOpen && (
        <div
          className="popover"
          style={{
            position: 'absolute',
            top: `${position.top}px`,
            left: `${position.left}px`
          }}
        >
          {content}
        </div>
      )}
    </>
  );
}

添加关闭行为和动画效果

实现点击外部关闭和简单的淡入淡出动画效果。

function Popover({ content, children }) {
  const [isOpen, setIsOpen] = useState(false);
  const popoverRef = useRef(null);

  useEffect(() => {
    const handleClickOutside = (event) => {
      if (popoverRef.current && !popoverRef.current.contains(event.target)) {
        setIsOpen(false);
      }
    };
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  return (
    <div className="popover-container">
      <span onClick={() => setIsOpen(true)}>{children}</span>
      <div
        ref={popoverRef}
        className={`popover ${isOpen ? 'fade-in' : 'fade-out'}`}
      >
        {content}
      </div>
    </div>
  );
}

使用第三方库实现

React 社区有许多成熟的 Popover 组件库可以直接使用。

import { Popover } from 'react-tiny-popover';

function Example() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <Popover
      isOpen={isOpen}
      positions={['top', 'bottom', 'left', 'right']}
      content={<div>Popover Content</div>}
    >
      <button onClick={() => setIsOpen(!isOpen)}>
        Toggle Popover
      </button>
    </Popover>
  );
}

样式基础

基本的 Popover 样式可以这样定义:

.popover {
  position: absolute;
  background: white;
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 10px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  z-index: 1000;
}

.fade-in {
  opacity: 1;
  transition: opacity 0.2s ease-in;
}

.fade-out {
  opacity: 0;
  transition: opacity 0.2s ease-out;
}

react popover实现

标签: reactpopover
分享给朋友:

相关文章

react native 如何

react native 如何

React Native 开发基础 React Native 是一个用于构建跨平台移动应用的框架,允许开发者使用 JavaScript 和 React 编写代码,同时生成原生 iOS 和 Androi…

如何配置react

如何配置react

配置React项目的步骤 安装Node.js和npm 确保系统已安装Node.js(包含npm)。可通过官网下载并安装最新版本。安装完成后,运行以下命令验证版本: node -v npm -v 创…

typescript react 如何

typescript react 如何

TypeScript 与 React 结合使用的方法 在 React 项目中使用 TypeScript 可以提升代码的可维护性和类型安全性。以下是一些关键步骤和最佳实践: 安装 TypeScript…

如何恢复react

如何恢复react

恢复 React 项目的方法 检查并修复依赖项 运行 npm install 或 yarn install 重新安装所有依赖项。如果依赖项损坏或缺失,这将恢复项目所需的库和工具。 恢复删除的文件 如…

react 如何操作cookie

react 如何操作cookie

安装依赖 在React项目中操作cookie通常需要第三方库的支持,推荐使用js-cookie。通过npm或yarn安装: npm install js-cookie # 或 yarn add js…

react路由如何配置

react路由如何配置

React 路由配置方法 安装 React Router 使用 npm 或 yarn 安装 React Router 的 DOM 版本: npm install react-router-dom…