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>
        )
    }
}
相关推荐
Jmyd01238 小时前
Web端3D营销展厅技术实现路径:从素材上云到线索回流的数据链路
前端·3d·性能优化·三维数字化
半个落月8 小时前
LangChain Agent 中间件实战(上):生命周期、状态、短路与工具包
javascript·langchain
砚凝霜8 小时前
【软考信息安全】第二十二章 Web服务器安全分析与增强——Apache与IIS
服务器·前端·安全
半个落月8 小时前
LangChain Agent 中间件实战(下):DeepAgents文件权限、长期记忆与对话摘要
javascript·langchain
u01110267510 小时前
JPG、PNG、WebP 怎么选?按透明度、体积和使用场景做判断
前端·javascript·vue.js·图像处理·ai作画
jerrywus10 小时前
让 AI 写完代码后交一份报告:我改造了 answer-me-with-html
前端·claude·cursor
派小心.11 小时前
小程序分享链路中来源参数的传递校验
大数据·前端·数据库·人工智能·小程序·数据分析
hhb_61811 小时前
一键生成数据看板,ECharts实战演示
前端·javascript·echarts
Java后端的Ai之路11 小时前
08_React组件API
前端·react.js·前端框架
小马不起床11 小时前
零基础玩转 FastAPI_09:前端基础工程构建
前端·状态模式·fastapi