react控制react Popover组件显示隐藏

1.antd版本

复制代码
"antd": "^3.26.16",

2.完整代码(因为要使用Modal.confirm,不使用e.target.closest查找class不太好控制)

复制代码
import React, { Component } from "react";
import { Select, Popover, DatePicker, Button, Modal } from "antd";

// 在不使用React.createRef的情况下,点击外层气泡外层隐藏,内层保持显示
export default class TestPopover extends Component {
    constructor(...args) {
        super(...args);
        this.state = {
            isShow: false
        }
        this.popoverRef = null; // 用于存储 Popover 内容区域的 DOM
        this.triggerRef = null; // 用于存储触发按钮的 DOM
    }
    componentWillMount() {
        // 使用mousedown速度比click快
        document.addEventListener("mousedown", this.onOutsideClick);
    }
    componentWillReceiveProps(nextProps) {
    }
    componentWillUnmount() {
        document.removeEventListener("mousedown", this.onOutsideClick);
    }

    // 全局点击处理
    onOutsideClick = (e) => {
        // 是否点击了【操作日志】按钮
        if (this.triggerRef?.contains(e.target)) {
            return;
        }
        // 是否点击了内容
        if (this.popoverRef?.contains(e.target)){
            return;
        }

        // e.target.closest是查找当前级和父级dom是否存在
        // antd弹窗(试了只能匹配class才比较好控制)
        if(e.target.closest(".ant-modal-wrap")){
            return;
        }

        // 其他情况 → 关闭
        this.setState({ isShow: false });
    };

    onDelete = ()=>{
        Modal.confirm({
            title: `确认删除吗?`,
            content: "",
            // centered: true,
            zIndex: 1500,
            okText: "确认",
            cancelText: "取消",
            onOk: () => {}
        })
    }

    togglePopover = ()=>{
        this.setState({
            isShow:!this.state.isShow
        })
    }

    render() {
        const content =  (
            <div style={{ width: "1100px"}} ref={(node) => (this.popoverRef = node)}>
                <div>
                    <div>
                        <div>
                            <Select
                                style={{width:"200px"}}
                                allowClear placeholder={"请选择"}
                                {/*下拉列表默认添加到body,绑定到父组件,避免点击下拉框隐藏当前content*/}
                                getPopupContainer={triggerNode => triggerNode.parentNode}
                            >
                                <Select.Option value="all" key="all">全部</Select.Option>
                            </Select>
                        </div>
                        <div>
                            <DatePicker
                                {/*下拉列表默认添加到body,绑定到父组件,避免点击下拉框隐藏当前content*/}
                                getCalendarContainer={triggerNode => triggerNode.parentNode}
                                allowClear placeholder={"请选择"}
                            />
                        </div>
                    </div>
                </div>
                <div>
                    <Button onClick={this.onDelete} type="danger">删除</Button>
                    <div>
                        <Button>
                            测试
                        </Button>
                    </div>
                    <div>
                        <Button>
                            测试
                        </Button>
                    </div>
                    <div>
                        <Button>
                            测试
                        </Button>
                    </div>
                    <div>
                        <Button>
                            测试
                        </Button>
                    </div>
                    <div>
                        <Button>
                            测试
                        </Button>
                    </div>
                    <div>
                        <Button>
                            测试
                        </Button>
                    </div>
                    <div>
                        <Button>
                            测试
                        </Button>
                    </div>
                    <div>
                        <Button>
                            测试
                        </Button>
                    </div>
                    <div>
                        <Button>
                            测试
                        </Button>
                    </div>
                    <div>
                        <Button>
                            测试
                        </Button>
                    </div>
                    <div>
                        <Button>
                            测试
                        </Button>
                    </div>
                    <div>
                        <Button>
                            测试
                        </Button>
                    </div>
                    <div>
                        <Button>
                            测试
                        </Button>
                    </div>
                </div>
            </div>
        );

        return (
            <Popover
                placement="bottomRight"
                content={content}
                visible={this.state.isShow}
                trigger="click"
            >
                <div  ref={(node) => (this.triggerRef = node)}>
                    <Button onClick={this.togglePopover}>
                        切换气泡
                    </Button>
                </div>
            </Popover>
        )
    }
}
相关推荐
创新技术阁11 分钟前
FastapiAdmin 系统日志体系与核心配置参数详解
前端·后端·fastapi
掘金酱12 分钟前
【社区公告】签到与矿石奖励解耦说明
前端
promiseThen14 分钟前
LWC Workflow:用 7 个 Cursor Skill 搭一条 AI 协作开发流水线
前端·ai编程
一个游离的指针36 分钟前
函数管道:消除深度嵌套调用
前端·javascript
浅诺1 小时前
Nginx sub_filter 的“幽灵陷阱”:为什么页面能打开,懒加载的 JS 却全是 404?
前端
PBitW1 小时前
为什么vite中TS报错,可以继续运行?Webpack不行?
前端·webpack·typescript·vite
光影少年1 小时前
react navite手写 FlatList 优化配置
前端·react native·react.js
曹牧1 小时前
C#:文本文件读取
服务器·前端·c#
柚yuzumi1 小时前
前端优化,从少触发一次开始:防抖与节流
前端·javascript
默_笙2 小时前
🚤 CSS 布局的"圈地运动":BFC 就是浏览器的独立领地
前端·javascript