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

Bootstrap模态框关闭控制:校验(含AJAX)通过才允许关闭,preventDefault后无法取消求解

原有代码的核心问题

  • 事件绑定逻辑错误:把保存按钮的click事件绑定写在hide.bs.modal的回调里,每次模态框触发隐藏时都会重复绑定点击事件,且hide事件触发时点击事件早已执行完毕,根本拿不到最新的校验状态
  • 变量逻辑写反:AJAX提交成功后你把cancel设为了true,反而会阻止模态框关闭,和你要的效果完全相反
  • 同步AJAX会阻塞浏览器,体验很差,不符合前端开发最佳实践

正确实现方案

实现思路:

  1. 单独给保存按钮绑定点击事件,所有表单校验、AJAX提交逻辑都在点击事件内完成
  2. 新增一个全局标记位allowClose,用来标识当前是不是校验通过的合法关闭操作
  3. 只有allowClose为true的时候才允许模态框关闭,否则拦截hide事件

修正后代码:

// 全局标记位,标识是否允许关闭模态框
let allowClose = false;

// 拦截模态框关闭事件
$('#modalAltaReceta').on('hide.bs.modal', function(e){
    // 只有标记位为true时才允许关闭
    if(!allowClose) {
        e.preventDefault();
        e.stopImmediatePropagation();
        return false;
    }
});

// 保存按钮点击逻辑,单独绑定,不要写在hide事件里
$("#grabarReceta").click(function() {
    let cancel = false;
    // 基础表单校验
    if($("#inputNombreReceta").val().trim()=="") {
        alert("请输入食谱名称");
        cancel = true;
    } else if($("#inputIntroReceta").val().trim()=="") {
        alert("请输入简短介绍");
        cancel = true;
    } else if($("#inputInstruccionesReceta").val().trim()=="") {
        alert("请填写食谱制作步骤");
        cancel = true;
    }
    
    let cantidadSinIngreso = 0;
    $(".inputIngredientes").each(function(index, item) {
        if(item.value.trim() == "")
            cantidadSinIngreso++
    });
    if(cantidadSinIngreso > 0) {                            
        cancel = true;
        alert("请至少填写一种食材");                                                   
    }

    // 基础校验不通过直接终止
    if(cancel) return;

    // 校验通过提交AJAX
    $.ajax({                                               
        url: 'php/recetas.php',
        async: true,
        type: 'POST',                      
        dataType: 'json',
        data: "tipo_id=grabarReceta&" + $("#frm_nueva_receta").serialize(),
        success: function(data) {  
            if(data['msg'] == 'ok') {
                // 提交成功,把允许关闭的标记位设为true
                allowClose = true;
                // 手动调用关闭模态框,这时候因为标记位是true,不会被拦截
                $('#modalAltaReceta').modal('hide');
                // 重置标记位,避免下次打开模态框时直接放行关闭
                setTimeout(()=> allowClose = false, 300);
                alert("保存成功");
            } else {
                alert("提交失败:" + data.msg);
            }                                      
        },
        error: function() {
            alert("网络请求失败,请重试");
        }
    });
});

如果你不需要拦截用户点击模态框右上角关闭按钮、点击模态框外空白区域的关闭操作,只需要控制点击保存按钮时的关闭逻辑,甚至可以去掉hide.bs.modal的拦截逻辑,直接在AJAX成功后调用$('#modalAltaReceta').modal('hide')即可,逻辑更简洁。

内容的提问来源于stack exchange,提问作者pablo Fiscella

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 17:06:04