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>
        )
    }
}
相关推荐
合作小小程序员小小店14 小时前
web开发,在线%超市销售%管理系统,基于idea,html,jsp,java,ssh,sql server数据库。
java·前端·sqlserver·ssh·intellij-idea
不爱学英文的码字机器15 小时前
重塑 Web 性能:用 Rust 与 WASM 构建“零开销”图像处理器
前端·rust·wasm
浩星15 小时前
react的框架UmiJs(五米)
前端·javascript·react.js
子醉17 小时前
推荐一种适合前端开发使用的解决本地跨域问题的办法
前端
Niyy_18 小时前
前端一个工程构建多个项目,记录一次工程搭建
前端·javascript
xiangxiongfly91518 小时前
CSS link标签
前端·css
快乐非自愿19 小时前
常用设计模式:工厂方法模式
javascript·设计模式·工厂方法模式
岁月宁静19 小时前
AI 多模态全栈应用项目描述
前端·vue.js·node.js
十年磨一剑~19 小时前
html+js开发一个测试工具
javascript·css·html