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

jQuery实现表单未保存离开时弹出自定义确认弹窗功能

jQuery表单未保存离开二次确认实现方案

原有代码问题梳理

  • 表单变更监听不全:select下拉选择、文件输入框的修改没有被监听,富文本textarea选择器漏写类前缀.,dropzone仅监听点击事件无法准确识别文件上传变更
  • 提交保存逻辑未做标记重置:点击保存按钮触发表单提交时,没有重置修改状态,会误弹出确认框
  • 事件逻辑不兼容浏览器规则:原生beforeunload事件受浏览器安全限制,无法直接唤起自定义模态框,需要配合页面内跳转拦截才能实现自定义弹窗效果
  • 模态框交互缺失:关闭、留在页面、离开页面三个操作没有绑定对应事件,无法正常交互

调整后完整代码

1. 自定义模态框微调(去掉硬编码跳转地址)

<div id="openModal" class="modalDialog" style="display: none;">
    <div>
        <a href="javascript:;" title="Close" class="close modal-stay">X</a>
        <h2>确定要离开当前页面吗?</h2>
        <p>您修改的内容尚未保存,离开后将丢失所有更改</p>
    </div>
    <a href="javascript:;" class="modal-leave">离开页面</a>
    <a href="javascript:;" class="modal-stay">留在页面</a>
</div>

2. jQuery逻辑代码

$(document).ready(function(){
    // 初始化修改标记、存储待跳转地址
    let isChanged = false;
    let pendingTarget = '';

    // 记录表单初始值,用于后续比对是否真的修改
    const $allFormFields = $('form input, form select, form textarea, .dropzone');
    const initialValues = {};
    $allFormFields.each(function(index){
        const fieldKey = `field_${index}`;
        initialValues[fieldKey] = $(this).val();
        $(this).data('fieldKey', fieldKey);
    });

    // 监听所有表单变更事件
    // 普通输入框、下拉选择、文本域变更
    $('form').on('input change', 'input, select, textarea', function(){
        const key = $(this).data('fieldKey');
        if($(this).val() !== initialValues[key]){
            isChanged = true;
        } else {
            // 检查是否所有字段都回到初始值,重置标记
            checkAllFieldReset();
        }
    });

    // 富文本编辑器内容变更(兼容富文本自动同步到textarea的场景)
    $('.rich_textarea').on('input propertychange paste', function() {
        const key = $(this).data('fieldKey');
        if($(this).val() !== initialValues[key]){
            isChanged = true;
        }
    });

    // Dropzone文件上传变更监听(替换原来的click监听,避免误判)
    if(window.Dropzone){
        Dropzone.forElement("#dropzone").on("addedfile removedfile", function() {
            isChanged = true;
        });
    }

    // 保存按钮点击时重置修改标记,提交表单不弹提示
    $('input[type="submit"]').on('click', function(){
        isChanged = false;
    });

    // 拦截页面内所有跳转链接
    $(document).on('click', 'a[href]', function(e){
        const href = $(this).attr('href');
        // 排除javascript:void(0)、锚点跳转这类不离开当前页的链接
        if(href.startsWith('javascript:') || href.startsWith('#')) return;
        if(isChanged){
            e.preventDefault();
            pendingTarget = href;
            $('#openModal').show();
        }
    });

    // 监听页面关闭/刷新/前进后退事件,弹出浏览器原生提示(自定义模态框无法在这个场景唤起,是浏览器安全限制)
    window.onbeforeunload = function(e){
        if(isChanged){
            e.preventDefault();
            e.returnValue = '您修改的内容尚未保存,确定要离开吗?';
            return e.returnValue;
        }
    };

    // 模态框交互逻辑
    // 留在页面/关闭弹窗
    $('.modal-stay').on('click', function(){
        pendingTarget = '';
        $('#openModal').hide();
    });
    // 离开页面
    $('.modal-leave').on('click', function(){
        isChanged = false;
        $('#openModal').hide();
        window.location.href = pendingTarget;
    });

    // 工具方法:检查所有字段是否回到初始值
    function checkAllFieldReset(){
        let allReset = true;
        $allFormFields.each(function(index){
            const key = $(this).data('fieldKey');
            if($(this).val() !== initialValues[key]){
                allReset = false;
                return false;
            }
        });
        isChanged = !allReset;
    }
});

实现说明

  • 点击保存按钮提交表单时,会自动重置修改状态,不会触发任何离开提示
  • 页面内点击链接跳转时,若有未保存修改会直接弹出自定义模态框,支持选择离开或留下
  • 刷新页面、关闭标签页、点击浏览器前进/后退按钮时,受浏览器安全限制无法展示自定义模态框,会弹出浏览器统一的确认提示,避免自定义代码被恶意站点滥用
  • 只有当表单内容和初始值不一致时才会标记为已修改,用户修改后又改回原值不会触发提示
  • Dropzone监听真实的文件增删事件,不会因为误点上传区域就触发未保存提示

注意:如果你的富文本编辑器是独立封装的(比如TinyMCE、CKEditor),需要额外给编辑器绑定内容变更事件同步标记状态,避免富文本内容修改无法被识别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:03:25