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>
        )
    }
}
相关推荐
Zuckjet_2 小时前
开启 3D 之旅 - 你的第一个 WebGL 三角形
前端·javascript·3d·webgl
2401_863801462 小时前
探索 12 种 3D 文件格式:综合指南
前端·3d
珍宝商店4 小时前
前端老旧项目全面性能优化指南与面试攻略
前端·面试·性能优化
bitbitDown4 小时前
四年前端分享给你的高效开发工具库
前端·javascript·vue.js
YAY_tyy4 小时前
【JavaScript 性能优化实战】第六篇:性能监控与自动化优化
javascript·性能优化·自动化
gnip5 小时前
实现AI对话光标跟随效果
前端·javascript
脑花儿5 小时前
ABAP SMW0下载Excel模板并填充&&剪切板方式粘贴
java·前端·数据库
闭着眼睛学算法6 小时前
【华为OD机考正在更新】2025年双机位A卷真题【完全原创题解 | 详细考点分类 | 不断更新题目 | 六种主流语言Py+Java+Cpp+C+Js+Go】
java·c语言·javascript·c++·python·算法·华为od
烛阴6 小时前
【TS 设计模式完全指南】构建你的专属“通知中心”:深入观察者模式
javascript·设计模式·typescript
lumi.7 小时前
Vue.js 从入门到实践1:环境搭建、数据绑定与条件渲染
前端·javascript·vue.js