Skip to content
js
/**
 * 创建一个自定义的提示框
 * @param {string} titleText 提示框标题
 * @param {string} contentText 提示框内容
 * @param {function} fn 点击确定或取消后的回调函数,参数为布尔值表示选择
 * @param {Object} config 配置对象,可用于自定义提示框的外观和行为
 * @配置对象属性说明:
 *    - width: 提示框宽度
 *    - height: 提示框高度
 *    - padding: 提示框内边距
 *    - borderRadius: 提示框圆角大小
 */
function myPrompt(titleText="标题", contentText="内容", fn=(function(){}), config) {
    config = {
         width:300,
         height:200,
         padding:10,
         borderRadius:10,
         ...config,
    }

    // 创建外部容器,用于遮盖整个页面
    const container = document.createElement("div");
    // 设置容器样式,以全屏显示并半透明
    container.style.width = "100vw";
    container.style.height = "100vh";
    container.style.backgroundColor = "rgba(0,0,0,0.5)";
    container.style.position = "fixed";
    container.style.zIndex = 9999;
    container.style.left = 0;
    container.style.top = 0;

    // 创建提示框主体
    const promp = document.createElement("div");
    // 根据配置设置提示框大小和样式
    promp.style.width = config.width  + "px";
    promp.style.height = config.height+ "px";
    promp.style.backgroundColor = "#fff";
    promp.style.boxSizing = "border-box";
    promp.style.padding = config.padding + "px";
    promp.style.position = "absolute";
    promp.style.top = "50%";
    promp.style.left = "50%";
    promp.style.transform = "translate(-50%,-50%)";
    promp.style.borderRadius = config.borderRadius + "px";

    // 创建关闭按钮
    const close = document.createElement("div");
    close.innerHTML = "X";
    close.style.position = "absolute";
    close.style.right = "10px";
    close.style.top = "10px";
    close.style.cursor = "pointer";
    // 绑定关闭按钮点击事件,关闭提示框并调用回调函数
    close.addEventListener("click", function () {
        container.remove();
        fn(null);
    });

    // 创建标题栏
    const title = document.createElement("div");
    title.style.width = "100%";
    title.innerHTML = titleText;
    title.style.textAlign = "center";
    title.style.fontSize = "20px";
    title.style.marginTop = "10px";
    title.style.userSelect = "none";
    title.style.cursor = "move";
    // 绑定标题栏拖动事件,允许提示框被拖动
    function mouseMove(e) {
        // 鼠标移动时更新提示框位置
        const left = parseFloat(window.getComputedStyle(promp).left);
        const top = parseFloat(window.getComputedStyle(promp).top);
        const mouseLeft = e.clientX;
        const mouseTop = e.clientY;

        function move(e) {
            // 计算拖动距离并更新提示框位置
            let disX = e.clientX - mouseLeft;
            let disY = e.clientY - mouseTop;
            let currentLeft = left + disX;
            let currentTop = top + disY;
            // 确保提示框不会拖出屏幕边界
            if (currentLeft <= parseFloat(promp.style.width) * 0.5) {
                currentLeft = parseFloat(promp.style.width) * 0.5;
            }
            if (currentTop <= parseFloat(promp.style.height) * 0.5) {
                currentTop = parseFloat(promp.style.height) * 0.5;
            }
            if (
                currentLeft >=
                document.documentElement.clientWidth -
                    parseFloat(promp.style.width) * 0.5
            ) {
                currentLeft =
                    document.documentElement.clientWidth -
                    parseFloat(promp.style.width) * 0.5;
            }
            if (
                currentTop >=
                document.documentElement.clientHeight -
                    parseFloat(promp.style.height) * 0.5
            ) {
                currentTop =
                    document.documentElement.clientHeight -
                    parseFloat(promp.style.height) * 0.5;
            }
            promp.style.left = currentLeft + "px";
            promp.style.top = currentTop + "px";
        }

        container.addEventListener("mousemove", move);

        container.addEventListener("mouseup", function () {
            container.removeEventListener("mousemove", move);
        });
    }
    title.addEventListener("mousedown", mouseMove);

    // 创建提示框内容区
    const txt = document.createElement("div");
    txt.style.position = "absolute";
    txt.style.top = "50%";
    txt.style.left = "50%";
    txt.style.transform = "translate(-50%, -50%)";
    txt.style.maxHeight = parseInt(promp.style.width) - 200 + "px";
    txt.style.maxWidth = parseInt(promp.style.width) - 50 + "px";
    txt.style.overflow = "auto";
    txt.innerHTML = contentText;

    // 创建确定和取消按钮
    const yes = document.createElement("div");
    const no = document.createElement("div");
    yes.style.position = "absolute";
    no.style.position = "absolute";
    yes.style.bottom = no.style.bottom = "10px";
    yes.style.left = "20%";
    no.style.right = "20%";
    yes.style.padding = no.style.padding = "5px 10px";
    yes.style.userSelect = no.style.userSelect = "none";
    yes.style.cursor = no.style.cursor = "pointer";
    yes.style.border = no.style.border = "1px solid #ccc";
    yes.style.borderRadius = no.style.borderRadius = "5px";
    yes.innerText = "确定";
    no.innerText = "取消";
    // 绑定按钮点击事件,根据选择调用回调函数
    yes.addEventListener("click", function () {
        container.remove();
        fn(true);
    });
    no.addEventListener("click", function () {
        container.remove();
        fn(false);
    });

    // 添加鼠标移入和移出事件,改变按钮背景色
    function mouseIn() {
        this.style.backgroundColor = "#eee";
    }
    function mouseOut() {
        this.style.backgroundColor = "#fff";
    }
    yes.addEventListener("mouseenter", mouseIn);
    yes.addEventListener("mouseout", mouseOut);
    no.addEventListener("mouseenter", mouseIn);
    no.addEventListener("mouseout", mouseOut);

    // 将元素添加到提示框和页面中
    promp.append(close, title, txt, yes, no);
    container.append(promp);
    document.documentElement.append(container);

    // 页面大小改变时调整提示框位置
    window.addEventListener("resize", function (e) {
        let currentLeft = parseFloat(promp.style.left);
        let currentTop = parseFloat(promp.style.top);
        if (currentLeft <= parseFloat(promp.style.width) * 0.5) {
            currentLeft = parseFloat(promp.style.width) * 0.5;
        }
        if (currentTop <= parseFloat(promp.style.height) * 0.5) {
            currentTop = parseFloat(promp.style.height) * 0.5;
        }
        if (
            currentLeft >=
            document.documentElement.clientWidth -
                parseFloat(promp.style.width) * 0.5
        ) {
            currentLeft =
                document.documentElement.clientWidth -
                parseFloat(promp.style.width) * 0.5;
        }
        if (
            currentTop >=
            document.documentElement.clientHeight -
                parseFloat(promp.style.height) * 0.5
        ) {
            currentTop =
                document.documentElement.clientHeight -
                parseFloat(promp.style.height) * 0.5;
        }
        promp.style.left = currentLeft + "px";
        promp.style.top = currentTop + "px";
    });
}

以笔记为镜,可以知得失