原生 js 实现思源 Dialog 对话框

/*
options = {
    ...options,
    showAction?: boolean,
    // 当点击确定后不想关闭对话框时,可设置为options.disableClose=true;即可
    confirmCallback?: (options?: IObject) => void
}
*/
// 创建基础对话框,createDialog基础上增加content容器和确定与取消按钮
// 当点击确定后不想关闭对话框时,可设置为options.disableClose=true;即可
function showBasicDialog(options) {
    options.width = options.width || "min(100%, 500px)";
    options.height = options.height || "min(100vh, 300px)";
    const showAction = options?.showAction === false  ? false : true;
    const actionHtml = showAction ? `
    <div class="b3-dialog__action">
        <button class="b3-button b3-button--cancel">取消</button><div class="fn__space"></div>
        <button class="b3-button b3-button--text">确定</button>
    </div>` : '';
    options.content = `
    <div class="b3-dialog__content">
        ${options.content}
    </div>
    ${actionHtml}`;
    const element = createDialog(options);
    if(showAction) {
        element.querySelector(".b3-button--text").addEventListener("click", (event) => {
            if(typeof options.confirmCallback === 'function') options.confirmCallback(element, options);
            if (!options.disableClose) {
                destroyDialog(element, options);
            }
            event.preventDefault();
            event.stopPropagation();
        });
        element.querySelector(".b3-button--cancel").addEventListener("click", (event) => {
            if (!options.disableClose) {
                destroyDialog(element, options);
            }
            event.preventDefault();
            event.stopPropagation();
        });
    }
}
/*
options = {
    title?: string,
    content: string,
    transparent?: boolean,
    width?: string,
    height?: string,
    left?: string,
    top?: string,
    destroyCallback?: (options?: IObject) => void,
    disableClose?: boolean,
    hideCloseIcon?: boolean,
    disableAnimation?: boolean,
    containerClassName?: string,
}*/
// 创建对话框
// 当不想关闭对话框时,可设置为options.disableClose=true;即可
function showDialog(options) {
    const disableClose = options.disableClose;
    const destroyCallback = options.destroyCallback;
    const element = document.createElement("div");
    let left = options.left;
    let top = options.top;
    element.innerHTML = `<div class="b3-dialog" style="z-index: ${++window.siyuan.zIndex};${typeof left === "string" ? "display:block" : ""}">
<div class="b3-dialog__scrim"${options.transparent ? 'style="background-color:transparent"' : ""}></div>
<div class="b3-dialog__container ${options.containerClassName || ""}" style="width:${options.width || "auto"};height:${options.height || "auto"};
left:${left || "auto"};top:${top || "auto"}">
<svg ${(!!document.getElementById("sidebar") && options.title) ? 'style="top:0;right:0;"' : ""} class="b3-dialog__close${(disableClose || options.hideCloseIcon) ? " fn__none" : ""}"><use xlink:href="#iconCloseRound"></use></svg>
<div class="resize__move b3-dialog__header${options.title ? "" : " fn__none"}" onselectstart="return false;">${options.title || ""}</div>
<div class="b3-dialog__body">${options.content}</div>
<div class="resize__rd"></div><div class="resize__ld"></div><div class="resize__lt"></div><div class="resize__rt"></div><div class="resize__r"></div><div class="resize__d"></div><div class="resize__t"></div><div class="resize__l"></div>
</div></div>`;
    element.querySelector(".b3-dialog__scrim").addEventListener("click", (event) => {
        if (!disableClose) {
            destroyDialog(element, options);
        }
        event.preventDefault();
        event.stopPropagation();
    });
    if (!disableClose) {
        element.querySelector(".b3-dialog__close").addEventListener("click", (event) => {
            destroyDialog(element, options);
            event.preventDefault();
            event.stopPropagation();
        });
    }
    document.body.append(element);
    if (options.disableAnimation) {
        element.classList.add("b3-dialog--open");
    } else {
        setTimeout(() => {
            element.classList.add("b3-dialog--open");
        });
    }
    return element;
}
function destroyDialog(element, options) {
    element.classList.remove("b3-dialog--open");
    setTimeout(() => {
        // av 修改列头emoji后点击关闭emoji图标
        if ((element.querySelector(".b3-dialog")).style.zIndex < window.siyuan.menus.menu.element.style.zIndex) {
            // https://github.com/siyuan-note/siyuan/issues/6783
            window.siyuan.menus.menu.remove();
        }
        element.remove();
        if (options.destroyCallback) {
            options.destroyCallback(options);
        }
        // https://github.com/siyuan-note/siyuan/issues/10475
        document.getElementById("drag")?.classList.remove("fn__hidden");
    }, 190);
}
image.png

留下你的脚步
推荐阅读