You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止Material Web组件mdc-dialog的[确定]按钮自动关闭弹窗?

阻止MDC Dialog确定按钮自动关闭的解决方案

问题背景

我使用HTML、JavaScript及Webpack构建了基于Material Design Components的Web应用,页面中使用mdc-dialog组件作为数据输入弹窗。弹窗的mdc-dialog__actions区域包含「取消」和「确定」按钮,我为「确定」按钮添加了自定义CSS类,用于在保存前自定义验证数据:若输入数据未通过验证,将弹出错误提示弹窗,同时主输入弹窗保持显示。但实际运行时,点击「确定」按钮后主输入弹窗会自动关闭。

相关代码

HTML代码

<div class="dialog-add-userpass mdc-dialog mdc-dialog--fullscreen">
    <div class="mdc-dialog__container">
        <div class="mdc-dialog__surface" role="dialog" aria-modal="true" aria-labelledby="my-dialog-title" aria-describedby="my-dialog-content">
            <div class="mdc-dialog__header">
                <h2 class="mdc-dialog__title" id="my-dialog-title">Add new User-Pass</h2>
                <button class="mdc-icon-button material-icons mdc-dialog__close" data-mdc-dialog-action="close">close</button>
            </div>
            <div class="mdc-dialog__content" id="my-dialog-content">
                <label class="txt-new-pass-no mdc-text-field mdc-text-field--outlined w-100p">
                    <span class="mdc-notched-outline">
                        <span class="mdc-notched-outline__leading"></span>
                        <span class="mdc-notched-outline__notch">
                            <span class="mdc-floating-label" id="lbl-pass-no">Pass No.</span>
                        </span>
                        <span class="mdc-notched-outline__trailing"></span>
                    </span>
                    <input type="text" class="mdc-text-field__input" aria-labelledby="lbl-pass-no" aria-controls="pass-no-help" aria-describedby="pass-no-help" id="inputPassNo" required minlength="4">
                </label>
                <!-- 省略其他表单内容 -->
                <div class="mdc-dialog__actions">
                    <button type="button" class="mdc-button mdc-dialog__button" data-mdc-dialog-action="cancel">
                        <div class="mdc-button__ripple"></div>
                        <span class="mdc-button__label">Cancel</span>
                    </button>
                    <button type="button" class="btn-add-save mdc-button mdc-dialog__button" data-mdc-dialog-action="ok">
                        <div class="mdc-button__ripple"></div>
                        <span class="mdc-button__label">Add new</span>
                    </button>
                </div>
            </div>
        </div>
    </div>
    <div class="mdc-dialog__scrim"></div>
</div>

JavaScript代码

import { MDCDialog } from '@material/dialog';

const dialogAddUserPass = new MDCDialog(document.querySelector('.dialog-add-userpass'));
dialogAddUserPass.scrimClickAction = "";
dialogAddUserPass.escapeKeyAction = "";

// 省略其他初始化代码

const btnAddSave = document.querySelector(".btn-add-save");
btnAddSave.addEventListener('click', async (e) => {
    e.preventDefault();
    txtPassNo.value = txtPassNo.value.trim();
    txtPassCode.value = txtPassCode.value.trim();
    txtEmail.value = txtEmail.value.trim();
    txtFullName.value = txtFullName.value.trim();
    
    // 省略验证逻辑
    } else {
        displayDialogMessage(validAddNew.message);
        dialogAddUserPass.open();
    }
});

解决方案

方案一:移除自动关闭触发属性

MDC Dialog会自动为带有data-mdc-dialog-action属性的按钮绑定关闭逻辑,直接移除「确定」按钮的该属性,即可阻止自动关闭,之后在验证通过时手动调用关闭方法。

  1. 修改HTML中的确定按钮:
<button type="button" class="btn-add-save mdc-button mdc-dialog__button">
    <div class="mdc-button__ripple"></div>
    <span class="mdc-button__label">Add new</span>
</button>
  1. 修改JavaScript点击事件,验证通过后手动关闭弹窗:
const btnAddSave = document.querySelector(".btn-add-save");
btnAddSave.addEventListener('click', async (e) => {
    e.preventDefault();
    txtPassNo.value = txtPassNo.value.trim();
    txtPassCode.value = txtPassCode.value.trim();
    txtEmail.value = txtEmail.value.trim();
    txtFullName.value = txtFullName.value.trim();
    
    // 执行自定义验证
    if (validAddNew.isValid) {
        // 这里添加保存数据的逻辑
        await saveUserPassData();
        // 验证通过,手动关闭弹窗
        dialogAddUserPass.close();
    } else {
        displayDialogMessage(validAddNew.message);
        // 弹窗不会自动关闭,无需再次调用open()
    }
});

方案二:监听关闭事件并拦截

如果需要保留data-mdc-dialog-action属性,可以通过监听MDCDialog:closing事件,在验证不通过时阻止默认关闭行为。

修改JavaScript代码,添加事件监听:

import { MDCDialog } from '@material/dialog';

const dialogAddUserPass = new MDCDialog(document.querySelector('.dialog-add-userpass'));
dialogAddUserPass.scrimClickAction = "";
dialogAddUserPass.escapeKeyAction = "";

// 监听弹窗关闭前的事件
dialogAddUserPass.listen('MDCDialog:closing', (event) => {
    // 判断是否是点击了确定按钮,且验证不通过
    if (event.detail.action === 'ok' && !validAddNew.isValid) {
        // 阻止弹窗关闭
        event.preventDefault();
        // 显示错误提示
        displayDialogMessage(validAddNew.message);
    }
});

// 原有点击事件可以保留,专注于数据处理
const btnAddSave = document.querySelector(".btn-add-save");
btnAddSave.addEventListener('click', async (e) => {
    e.preventDefault();
    txtPassNo.value = txtPassNo.value.trim();
    txtPassCode.value = txtPassCode.value.trim();
    txtEmail.value = txtEmail.value.trim();
    txtFullName.value = txtFullName.value.trim();
    
    // 执行自定义验证逻辑,更新validAddNew状态
    validAddNew = validateUserPassData();
});

内容的提问来源于stack exchange,提问作者Jatu Tung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 20:47:34