javascript 当点击里面的输入按钮时,Modal会消失(ReactJS)

v6ylcynt  于 2023-08-02  发布在  Java
关注(0)|答案(1)|浏览(113)

我有以下模态元素:

import { useState } from "react";

import { MouseEvent, useEffect, useRef } from "react";
import CloseIcon from "../assets/close-icon.svg";
import { ImagesIcon } from ".";

export const DialogModalTester = () => {
    const [isOpened, setIsOpened] = useState(false);

    const onProceed = () => {
        console.log("Proceed clicked");
    };

    // Image
    function displayFile(file: any) {
        let fileType = file.type;
        let validExtensions = ["image/jpeg", "image/jpg", "image/png"];
        if (validExtensions.includes(fileType)) {
            console.log("Approved");
            let img = "";
            dragAreaRef.current.innerHTML = img;
        } else {
            // add warning info
            dragAreaRef.current.classList.remove("active");
        }
    }

    let onDragOver = (event: any) => {
        event.preventDefault();
        dragAndDropRef.current.textContent = "Release to Upload";
        dragAreaRef.current.classList.add("active");
    };

    let onDragLeave = (event: any) => {
        dragAndDropRef.current.textContent = "Drag & Drop";
        dragAreaRef.current.classList.remove("active");
    };

    let onDrop = (event: any) => {
        event.preventDefault();
        let file;
        file = event.dataTransfer.files[0];
        console.log(file);
        displayFile(file);
    };

    let dragAreaRef = useRef<any>(null);
    let dragAndDropRef = useRef<any>(null);
    let browseInputRef = useRef<any>(null);

    let inputChange = () => {
        let file = browseInputRef.current.files[0];
        dragAreaRef.current.classList.add("active");
        displayFile(file);
    };

    return (
        <div>
            <button onClick={() => setIsOpened(true)}>Open "dialog" modal</button>

            <DialogModal isOpened={isOpened} onClose={() => setIsOpened(false)}>
                <div id="image-modal">
                    <div className="upload-container">
                        <div className="header">
                            <h1>Image</h1>
                            <button className="close-btn" onClick={() => setIsOpened(false)}>
                                <img src={CloseIcon}></img>
                            </button>
                        </div>
                        <div
                            className="drag-area"
                            ref={dragAreaRef}
                            onDragOver={onDragOver}
                            onDragLeave={onDragLeave}
                            onDrop={onDrop}
                        >
                            <div className="icon">
                                <ImagesIcon />
                            </div>

                            <span ref={dragAndDropRef} className="drag-and-drop">
                                Drag & Drop{" "}
                            </span>
                            <span className="browse">
                                or{" "}
                                <span
                                    onClick={() => browseInputRef.current.click()}
                                    className="browse-btn"
                                >
                                    browse
                                </span>
                            </span>
                            <input ref={browseInputRef} type="file" hidden></input>
                            <span className="support">Supports: JPEG, JPG, PNG</span>
                        </div>
                    </div>
                </div>
            </DialogModal>
        </div>
    );
};

const isClickInsideRectangle = (e: MouseEvent, element: HTMLElement) => {
    const r = element.getBoundingClientRect();

    return (
        e.clientX > r.left &&
        e.clientX < r.right &&
        e.clientY > r.top &&
        e.clientY < r.bottom
    );
};

type Props = {
    isOpened: boolean;
    onClose: () => void;
    children: React.ReactNode;
};

const DialogModal = ({ isOpened, onClose, children }: Props) => {
    const ref = useRef<HTMLDialogElement>(null);

    useEffect(() => {
        if (isOpened) {
            ref.current?.showModal();
            document.body.classList.add("modal-open"); // prevent bg scroll
        } else {
            ref.current?.close();
            document.body.classList.remove("modal-open");
        }
    }, [isOpened]);

    return (
        <div
            className="modal-overlay"
            onClick={(e) =>
                ref.current && !isClickInsideRectangle(e, ref.current) && onClose()
            }
        >
            <dialog className="modal-dialog" ref={ref} onCancel={onClose}>
                {children}
            </dialog>
        </div>
    );
};

export default DialogModal;

字符串
问题是,当我点击browse按钮时,模态被关闭。我想关闭模态只有当确实,点击它外面。我该改什么?

mwg9r5ms

mwg9r5ms1#

我看到的问题是dialog元素上的onClick处理程序,它检查单击是否在对话框内,如果不是,它调用onClose函数,关闭模态。
您可以在modal-overlay div类上使用onClick,而不是在dialog元素上使用onClick

const DialogModal = ({ isOpened, onClose, children }: Props) => {
    const ref = useRef<HTMLDialogElement>(null);

    useEffect(() => {
        if (isOpened) {
            ref.current?.showModal();
            document.body.classList.add("modal-open"); // prevent bg scroll
        } else {
            ref.current?.close();
            document.body.classList.remove("modal-open");
        }
    }, [isOpened]);

    return (
        <div
            className="modal-overlay"
            onClick={(e) =>
                ref.current && !isClickInsideRectangle(e, ref.current) && onClose()
            }
        >
            <dialog className="modal-dialog" ref={ref} onCancel={onClose}>
                {children}
            </dialog>
        </div>
    );
};

字符串

更新方法

const DialogModal = ({ isOpened, onClose, children }: Props) => {
    const ref = useRef<HTMLDialogElement>(null);

    useEffect(() => {
        if (isOpened) {
            ref.current?.showModal();
            document.body.classList.add("modal-open"); // prevent bg scroll
        } else {
            ref.current?.close();
            document.body.classList.remove("modal-open");
        }
    }, [isOpened]);

    const handleClick = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
        if (!ref.current?.contains(e.target as Node)) {
            onClose();
        }
    }

    return (
        <div className="modal-overlay" onClick={handleClick}>
            <dialog className="modal-dialog" ref={ref} onCancel={onClose}>
                {children}
            </dialog>
        </div>
    );
};

相关问题