Bootstrap模态框-隐藏一个然后显示另一个

6

我一直在使用jQueryUI,但最近因为美观的原因切换到了Bootstrap。现在我遇到了一个简单的问题,希望更熟悉Bootstrap的人能够帮助我。

我有一个通用的函数,用于动态创建对话框。有时候我会显示没有按钮的对话框(例如处理中),然后将其切换到具有按钮的对话框(例如处理完成-点击“确定”)。我不想定义一个固定的过程,所以基本上我想要能够在需要时关闭一个对话框并打开另一个对话框。这就是问题所在。

使用Bootstrap时,对话框会有动画效果,我喜欢这个效果并希望保留它。但是,当切换对话框时,我不想使用动画效果。我可以通过在第一个对话框显示时从中删除类fade,在第二个对话框显示之前从中删除类,并且这样做非常好。然后我将类添加到第二个对话框中,以便它会有动画效果。然而,当我这样做时,动画效果会出错,并且背景div应该缓慢淡出的地方会出现难看的闪光。

我已经准备了一个jsfiddle来演示这个问题。您可以单击第一个对话框上的关闭按钮,以查看淡出动画应该是什么样子。

在我开始研究Bootstrap源文件之前,任何帮助都将不胜感激。

http://jsfiddle.net/ArchersFiddle/0302gLav/1/

tl;dr

查看jsfiddle-单击“显示对话框2”-单击“确定”。我想消除最后的黑色闪光。

CSS

@import url("//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css");
.modal {
    display: none;
}

HTML

<div id="dialog1" class="modal fade">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title">Modal Dialog 1</h4>
      </div>
      <div class="modal-body">This is the first modal dialog</div>
      <div class="modal-footer">
        <button type="button" id="dialog-ok" class="btn btn-default">Show dialog 2</button>          
        <button type="button" id="dialog-close" class="btn btn-default" data-dismiss="modal">Close</button>          
      </div>
    </div>
  </div>
</div>

<div id="dialog2" class="modal">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title">Modal Dialog 2</h4>
      </div>
      <div class="modal-body">This is the second modal dialog</div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">OK</button>          
      </div>
    </div>
  </div>
</div>

JavaScript

function showDialog2() {
    $("#dialog1").removeClass("fade").modal("hide");
    $("#dialog2").modal("show").addClass("fade");
}

$("#dialog1").modal("show");

$("#dialog-ok").on("click", function() {
    showDialog2();
});
5个回答

4
function showDialog2() {
$("#dialog1").removeClass("fade").modal("hide");
$("#dialog2").addClass("fade").modal("show");

你想成为 这个


谢谢,但是两个对话框之间有一个明显的动画效果。如果您查看我的jsfiddle,您会发现没有这种情况。 - Reinstate Monica Cellio
2
删除“fade”类对我有用,这个fiddle存在一个bug,第二个对话框也必须删除“fade”类,而不是添加它。 - snovity

4

更新:

我为您最后一个按钮添加了一个click()处理程序,并添加了一个测试标识符id="test",其中对话框和背景使用fadeOut()效果淡出。重要的是要淡出封装对话框和背景的元素.modal-backdrop

$("#test").on("click", function () {
    $(".modal-backdrop").fadeOut("slow");
});

JsFiddle


谢谢,其实这并不糟糕。但我想使用Bootstrap内置的动画效果来完成它。例如,类“in”用于处理对话框的动画效果,在未来可能会更改以允许其他选项,因此我不想硬编码任何当前由Bootstrap完成的内容。请参见此处的示例...http://jsfiddle.net/ArchersFiddle/fvr5Lpnn/2/ - Reinstate Monica Cellio
我喜欢你使用 removeClass("in") 的方式,但我确实理解你是如何处理对话框以及为什么硬编码并不是明智的选择。这也是我一开始尝试避免的,但似乎当你覆盖默认功能时,会出现闪烁问题。 - urbz
正是我的问题,没错。我目前采用的解决方案基本上就是这个答案(使用in类)。由于这是一个正在40多个客户网站上运行的Web产品的一部分,因此我尽量让它尽可能通用。每当在网站中使用的控件添加了新选项时,我会通过他们的站点管理页面向客户公开这些选项。如果将来只需要将类从“in”更改为“bounce”,那么对我来说使用现有的Bootstrap功能将更加简单。尽管如此,我仍然感激您的帮助 :) - Reinstate Monica Cellio
我完全同意。我想出了一个更好的替代方案,但现在它仍然是肮脏的编码。;-) 我重新添加了Bootstrap中内置的动画属性data-dismiss="modal",并且只是淡化了包含对话框和背景的.modal-backdrop元素。请查看更新后的答案! - urbz
非常感谢你的帮助,但我仍然不满意,因为这不会触发Bootstrap模态框使用的任何事件处理程序,所以它不是未来可靠的。我选择了一种解决方案,完全解决了我能想到的所有问题,并将其发布为答案。感谢你的帮助,肯定+1 :) - Reinstate Monica Cellio

3

好的,我不喜欢回答自己的问题,但我有一个解决方案是100%可靠的(据我所知)。 我最终采用了一种解决方案,检查现有对话框并进行修改,而不是隐藏它并显示新的对话框。

这是一个工作的jsfiddle(在ajax调用中使用echo,其中通常加载html模板)...

http://jsfiddle.net/ArchersFiddle/0302gLav/9/

这段代码是我正在开发的较大库的一部分,但我仍会将它发布在此处,因为它可能对他人很有用。
JavaScript库
(function () {

    var _defaultOptions = {
        backdrop: "static",
        close: true,
        keyboard: true
    };

    window.bootstrap = {
        modal: {
            show: function (options) {

                options = $.extend(_defaultOptions, options);

                var buttonText = "";

                for (var key in options.buttons) {

                    options.buttons[key].id = "button_" + key.split(" ").join("");

                    var button = options.buttons[key];

                    buttonText += "<button type=\"button\" " +
                        "id=\"" + button.id + "\" " +
                        "class=\"btn " +
                        (typeof (button.class) == "undefined" ? "btn-default" : button.class) + "\" " +
                        (typeof (button.dismiss) == "undefined" ? "" : "data-dismiss=\"modal\" ") + ">" +
                        key + "</button>";
                }

                $.ajax({
                    url: "templates/bootstrap-modal.html"
                })
                .done(function (data) {
                    data = data
                        .replace("{:Title}", options.title)
                        .replace("{:Body}", options.body)
                        .replace("{:Buttons}", buttonText);

                    var $modal = $("#bootstrap-modal");
                    var existing = $modal.length;

                    if (existing) {
                        $modal.html($(data).find(".modal-dialog"));
                    }
                    else {
                        $modal = $(data).appendTo("body");
                    }

                    for (var key in options.buttons) {
                        var button = options.buttons[key];
                        if (typeof (button.callback) !== undefined) {
                            $("#" + button.id).on("click", button.callback);
                        }
                    }

                    $modal.off("shown.bs.modal").on("shown.bs.modal", function(e) {
                        if (typeof(options.onshow) === "function") {
                            options.onshow(e);
                        }
                    });

                    if (!existing) {
                        $modal.modal(options);
                    }

                    if (options.large === true) {
                        $modal.find(".modal-dialog").addClass("modal-lg");
                    }

                    if (options.close === false) {
                        $modal.find("button.close").remove();
                    }
                });
            },
            hide: function (callback) {
                var $modal = $("#bootstrap-modal");

                if (!$modal.length) return;

                $modal.on("hidden.bs.modal", function(e) {
                    $modal.remove();
                    if (typeof(callback) === "function") {
                        callback(e);
                    }
                });

                $modal.modal("hide");
            }
        }
    };
})();

模板 HTML

<div id="bootstrap-modal" class="modal fade">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
        <h4 class="modal-title">{:Title}</h4>
      </div>
      <div class="modal-body">{:Body}</div>
      <div class="modal-footer">
        {:Buttons}
      </div>
    </div>
  </div>
</div>

使用示例:

bootstrap.modal.show({
    title: "Dialog Title",
    body: "<p>This is the dialog body and can contain any old html rubbish.</p>",
    buttons: {
        Close: {
            dismiss: true
        }
    }
});

进一步解释的选项
bootstrap.modal.show({
    backdrop: true,                     // show the backdrop
    close: true,                        // show the close button
    keyboard: true,                     // allow the keyboard to close the dialog
    title: "Dialog Title",
    body: "<p>This is the dialog body and can contain any old html rubbish.</p>",
    buttons: {
        Button1: {
            class: "btn-primary",           // any class you want to add to the button
            dismiss: false,                 // does this button close the dialog?
            callback: function() {          // button click handler
                // the button was clicked - do something here
            }
        },
        Button2: {
            // options as defined as above.  You can have as many buttons as you want
        }
    },
    onshow: function(e) {
        // this will trigger when the dialog has completed the show animation
    }
});

并且

bootstrap.modal.hide(function(e) {
    // this will trigger when the dialog has completed the hide animation
});

所有show()方法中的选项都是可选的,但显然您需要一个标题和正文。

0

我已经编写了代码,可以在打开另一个模态框之前关闭已打开的模态框。

$('[data-toggle="modal"]').on('click', function() { //On click a button which call a modal
    if(($(".modal").data('bs.modal') || {}).isShown){ //If a modal is shown
        var modal = $(".modal.in"); // Get the current element
        $(modal).modal('hide'); // Hide the current modal
    }
});

希望这有所帮助!

谢谢,但不用了。如果你再读一遍问题,你会发现我想要消除关闭一个对话框和打开另一个对话框之间的动画。修改现有的对话框是最精确的方法。 - Reinstate Monica Cellio

0
有点晚了,但可能会帮助到遇到同样问题的人。
在显示新模态框时删除 fade 类会显示没有 fade 类的背景。
为了实现干净的过渡,隐藏当前模态框并在关闭时淡出而不是淡入来显示新模态框:
// hide the existing modal, but without fade animation
$("#existing-modal").removeClass("fade").modal("hide");

// show the new modal without fade animation, but enable the fade animation for later
$("#new-modal").removeClass("fade").modal("show").addClass("fade");

// enable fade animation of the backdrop, that was removed for the new modal
$(".modal-backdrop.in").addClass("fade");

使用最新的Bootstrap版本,使用 $(".modal-backdrop.show").addClass("fade")

修复后的示例:http://jsfiddle.net/bvalentino/f82z1wex/2/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接