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>
        )
    }
}
相关推荐
小陈工3 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“
开发语言·前端·javascript·数据库·vue.js·人工智能·python
xiaotao1317 小时前
第九章:Vite API 参考手册
前端·vite·前端打包
午安~婉7 小时前
Electron桌面应用聊天(续)
前端·javascript·electron
彧翎Pro8 小时前
基于 RO1 noetic 配置 robosense Helios 32(速腾) & xsense mti 300
前端·jvm
小码哥_常8 小时前
解锁系统设置新姿势:Activity嵌入全解析
前端
之歆8 小时前
前端存储方案对比:Cookie-Session-LocalStorage-IndexedDB
前端
哟哟耶耶8 小时前
vue3-单文件组件css功能(:deep,:slotted,:global,useCssModule,v-bind)
前端·javascript·css
是罐装可乐8 小时前
深入理解“句柄(Handle)“:从浏览器安全到文件系统访问
前端·javascript·安全
华科易迅9 小时前
Vue如何集成封装Axios
前端·javascript·vue.js
康一夏9 小时前
Next.js 13变化有多大?
前端·react·nextjs