如何使用antdesign的popover实现hover和click/focus弹出不同内容?

我想使用antdesign的popover实现以下效果

  • hover的时候可以弹出A
  • clickfocus的时候可以弹出B,此时hover弹出的A消失

行为类似于youtubehoverclickfocus评论区排序图标

  • clickfocus
    click or focus
  • hover
    hover
阅读 892
avatarAI BotBETA

在 Ant Design 的 Popover 组件中,你可以通过控制 visible 状态和监听不同的事件来实现 hoverclickfocus 时弹出不同内容的需求。下面是一个简单的示例代码,展示了如何实现这种效果:

import React, { useState, useEffect, useRef } from 'react';
import { Popover, Button } from 'antd';

const MyComponent = () => {
  const [isHoverVisible, setIsHoverVisible] = useState(false);
  const [isClickVisible, setIsClickVisible] = useState(false);
  const triggerRef = useRef(null);

  const handleVisibleChange = (visible, trigger) => {
    if (trigger === 'hover') {
      setIsHoverVisible(visible);
    } else if (trigger === 'focus' || trigger === 'click') {
      setIsClickVisible(visible);
    }
  };

  useEffect(() => {
    const handleOutsideClick = (event) => {
      if (triggerRef.current && !triggerRef.current.contains(event.target)) {
        setIsClickVisible(false);
      }
    };

    document.addEventListener('mousedown', handleOutsideClick);

    return () => {
      document.removeEventListener('mousedown', handleOutsideClick);
    };
  }, []);

  return (
    <div>
      <Popover
        visible={isHoverVisible}
        content="这是hover时弹出的内容A"
        trigger="hover"
        onVisibleChange={(visible) => handleVisibleChange(visible, 'hover')}
      >
        <Button ref={triggerRef}>Hover Me</Button>
      </Popover>
      <Popover
        visible={isClickVisible}
        content="这是click或focus时弹出的内容B"
        trigger={['click', 'focus']}
        onVisibleChange={(visible) => handleVisibleChange(visible, 'click')}
      >
        <Button ref={triggerRef}>Click or Focus Me</Button>
      </Popover>
    </div>
  );
};

export default MyComponent;

在上面的代码中,我们使用了两个 Popover 组件,一个用于 hover 事件,另一个用于 clickfocus 事件。我们为每个 Popover 组件维护了一个独立的 visible 状态,分别是 isHoverVisibleisClickVisible。通过 useStateuseEffect 来管理这些状态。

hover 事件触发时,我们更新 isHoverVisible 状态,显示或隐藏第一个 Popover。当 clickfocus 事件触发时,我们更新 isClickVisible 状态,显示或隐藏第二个 Popover

useEffect 钩子中,我们添加了一个全局的 mousedown 事件监听器,当点击事件发生在 Button 组件外部时,关闭通过 clickfocus 触发的 Popover。这是为了确保当用户点击其他地方时,通过 clickfocus 触发的 Popover 能够关闭。

请注意,这个示例假设你使用的是函数组件和 React Hooks。如果你使用的是类组件,那么你需要使用类组件的状态管理和生命周期方法来替代 useStateuseEffect

另外,代码中的 Button 组件的 ref 属性被同时赋给了两个 Popover 组件。这是为了简化示例,实际上你可能需要为每个 Popover 组件使用单独的 ref,并相应地调整事件监听逻辑。

1 个回答
✓ 已被采纳
function App() {
  const sortTypes = ["按热度", "最新"],
    [type, setType] = useState(sortTypes[0]),
    menu: MenuProps = {
      items: sortTypes.map((t, i) => ({
        key: i,
        label: t,
        onClick: () => setType(t),
      })),
    };

  return (
    <>
      <Dropdown menu={menu} trigger={["click"]}>
        <Popover content="评论排序" placement="bottom">
          <Flex gap="small">
            <AlignLeftOutlined />
            排序方式
          </Flex>
        </Popover>
      </Dropdown>
      排序方式:{type}
    </>
  );
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏