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

如何用jQuery 1.11模拟Bootstrap的modal相关事件

问题:jQuery 1.11中模拟Bootstrap模态框事件失效

场景描述

使用jQuery 1.11版本,想要模拟Bootstrap模态框的hide.bs.modal、hidden.bs.modal、show.bs.modal、shown.bs.modal事件,但调用$('#addProductModal').modal('hide')时,自定义的$.fn.modal.hide函数从未触发,只有全局的$.fn.hide会执行,且无报错。

原代码如下:

(function($) {
    var oldshow = $.fn.show;
    var oldhide = $.fn.hide;

    $.fn.show = function() {
        return oldshow.apply(this, arguments);
    };

    $.fn.modal.hide = function() { // <--从未触发
        console.log(`hiding modal 1: `, this);
        oldhide.apply(this, arguments);
        return this.modal.hidden.apply(this, arguments);
    };

    $.fn.hide.modal = function() { // <--从未触发
        console.log(`hiding modal 2: `, this);
        oldhide.apply(this, arguments);
        return this.modal.hidden.apply(this, arguments);
    };

    $.fn.hide = function() { // <---此函数触发
        console.log(`hiding modal 3: `, this);
        oldhide.apply(this, arguments);
        return this.modal.hidden.apply(this, arguments);
    };

    $.fn.modal.hidden = function() {
        if (this.tagName === `dialog` || this.attr(`role`) === `dialog`) {
            return this.trigger(`modal.hidden`);
        }
    };
})(jQuery);

$('#addProductModal').on(`modal.hidden`, function() { // <-- 通过$.fn.hide可正常触发
    console.log(`we triggered on hidden`);
});

问题根源

Bootstrap的modal()是一个接受命令参数的插件方法,而非直接挂载$.fn.modal.hide这类子方法。你的代码中直接给$.fn.modal添加hide属性,并不会被$(element).modal('hide')调用——因为这种调用方式是传入字符串命令,需要$.fn.modal函数内部去解析处理。

解决方案

重写$.fn.modal函数,让它能识别'show'、'hide'命令,触发对应的前置事件,执行显示/隐藏逻辑,再触发完成事件。同时保留原生show()/hide()的行为,确保非模态框元素不受影响。

修改后的完整代码:

(function($) {
    // 保存原生方法
    var oldShow = $.fn.show;
    var oldHide = $.fn.hide;

    // 重写modal插件方法,支持命令参数
    $.fn.modal = function(command) {
        // 遍历匹配的元素(jQuery插件惯例)
        return this.each(function() {
            var $modal = $(this);
            // 仅处理模态框元素(通过role="dialog"或dialog标签判断)
            if ($modal.is('[role="dialog"], dialog')) {
                switch(command) {
                    case 'show':
                        // 触发show.bs.modal事件(显示前)
                        $modal.trigger('show.bs.modal');
                        // 执行原生show方法
                        oldShow.call($modal);
                        // 触发shown.bs.modal事件(显示完成后)
                        $modal.trigger('shown.bs.modal');
                        break;
                    case 'hide':
                        // 触发hide.bs.modal事件(隐藏前)
                        $modal.trigger('hide.bs.modal');
                        // 执行原生hide方法
                        oldHide.call($modal);
                        // 触发hidden.bs.modal事件(隐藏完成后)
                        $modal.trigger('hidden.bs.modal');
                        break;
                    // 可扩展其他命令,比如'toggle'
                    case 'toggle':
                        if ($modal.is(':visible')) {
                            $modal.modal('hide');
                        } else {
                            $modal.modal('show');
                        }
                        break;
                }
            }
        });
    };

    // 可选:如果需要通过原生show()/hide()触发模态框事件,可重写这两个方法
    $.fn.show = function() {
        var result = oldShow.apply(this, arguments);
        // 对模态框元素触发shown事件
        this.filter('[role="dialog"], dialog').trigger('shown.bs.modal');
        return result;
    };

    $.fn.hide = function() {
        var result = oldHide.apply(this, arguments);
        // 对模态框元素触发hidden事件
        this.filter('[role="dialog"], dialog').trigger('hidden.bs.modal');
        return result;
    };
})(jQuery);

// 事件绑定示例
$('#addProductModal')
    .on('show.bs.modal', function() {
        console.log('模态框即将显示');
    })
    .on('shown.bs.modal', function() {
        console.log('模态框已显示');
    })
    .on('hide.bs.modal', function() {
        console.log('模态框即将隐藏');
    })
    .on('hidden.bs.modal', function() {
        console.log('模态框已隐藏');
    });

// 调用测试
// $('#addProductModal').modal('show');
// $('#addProductModal').modal('hide');

代码说明

  1. 重写$.fn.modal:遵循jQuery插件的遍历惯例,处理'show'/'hide'/'toggle'命令,先触发前置事件(show.bs.modal/hide.bs.modal),再执行原生显示/隐藏逻辑,最后触发完成事件(shown.bs.modal/hidden.bs.modal)。
  2. 模态框判断:仅对role="dialog"或<dialog>标签的元素触发事件,避免影响其他元素。
  3. 原生方法兼容:可选重写show()/hide(),让直接调用这两个方法时也能触发模态框事件,保持和Bootstrap行为一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 10:00:19