Twitter引导远程模式每次都会显示相同的内容


263

我正在使用Twitter引导程序,我已经指定了一个模式

<div class="modal hide" id="modal-item">

    <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">x</button>
        <h3>Update Item</h3>
    </div>

    <form action="http://www.website.com/update" method="POST" class="form-horizontal">

    <div class="modal-body">
        Loading content...
    </div>

    <div class="modal-footer">
        <a href="#" class="btn" data-dismiss="modal">Close</a>
        <button class="btn btn-primary" type="submit">Update Item</button>
    </div>

    </form>

</div>

和链接

<a href="http://www.website.com/item/1" data-target="#modal-item" data-toggle="modal">Edit 1</a>
<a href="http://www.website.com/item/2" data-target="#modal-item" data-toggle="modal">Edit 2</a>
<a href="http://www.website.com/item/3" data-target="#modal-item" data-toggle="modal">Edit 2</a>

当我第一次单击任何一个链接时,我看到正确的内容,但是当我单击其他链接时,它显示第一次加载相同的内容,但不会更新该内容。

我希望它每次被单击时都进行更新。

PS:我可以通过自定义jQuery函数轻松地使其工作,但是我想知道是否可以使用本机Bootstrap模态远程功能,因为它应该很容易,我想这只是使事情变得复杂。


相同的修复程序,但针对Bootstrap 3进行了修改。Bootstrap 3引入了名称空间。plnkr.co/edit/HWSgSw?p=preview
Jeff H

5
请注意,remote自Bootstrap v3.2.1起模态已弃用,而在v4中将消失。
cvrebert

Answers:


447

问题是双重的。

首先,实例化Modal对象后,它会永久地附加到由data-target以及随后的调用指定的元素上,以表明modal将仅对其调用toggle(),而不会更新。中的值options。因此,即使href您的不同链接上的属性不同,但切换模式时,其值remote也不会更新。对于大多数选项,可以通过直接编辑对象来解决此问题。例如:

$('#myModal').data('bs.modal').options.remote = "http://website.com/item/7";

但是,在这种情况下这是行不通的,因为...

其次,Modal插件旨在将远程资源加载到Modal对象的构造函数中,不幸的是,这意味着即使对进行了更改options.remote也永远不会重新加载

一种简单的补救方法是在随后的切换之前销毁Modal对象。一种选择是在隐藏完成后销毁它:

$('body').on('hidden.bs.modal', '.modal', function () {
  $(this).removeData('bs.modal');
});

注意:根据需要调整选择器。这是最一般的。

柱塞

或者,您可以尝试提出一种更复杂的方案来执行类似的操作,例如检查启动模式的链接是否不同于先前的链接。如果是,请销毁;否则,请销毁。如果不是,则无需重新加载。


1
@VladimirStarkov抱歉,似乎我忘记了hide模式上的类,因此,如果您的窗口太小,则模式可能已阻止了按钮上的鼠标事件。由于某种原因,JSFiddle.net今天早上真的很糟糕(得到了504个试图更新的信息),因此我只是在plnkr.co上重新编写了示例,无论如何它对于AJAX还是更好的。
Merv 2012年

3
还有一个问题:.modal-body仍将包含文本,因此我添加了:<CODE> $('#myModal .modal-body')。text(“ Loading ...”)</ CODE>在隐藏的事件监听器中
rbp

5
bs.modal$(this).removeData('bs.modal')为我工作与引导3
jvannistelrooy

2
Boostrap 3的完整工作代码是$('body').on('hidden.bs.modal', '.modal', function () { $(this).removeData('bs.modal'); });
Christophe

1
我还将检查是否从远程源加载了被隐藏的模态,以免破坏带有静态内容的模态: var modalData = $(this).data('bs.modal'); if (modalData && modalData.options.remote)...
Wojtek Kruszewski 2016年

171

对于引导程序3,您应使用:

$('body').on('hidden.bs.modal', '.modal', function () {
    $(this).removeData('bs.modal');
});

17
我的英雄。喜欢这些未记录的更改。
乔林(Jorin)2013年

2
这很有帮助。Bootstrap 3不向后兼容,因此SO(或其他论坛)上的大多数内容都是关于BS <3的,尝试这些解决方案确实浪费了很多时间。
Swapnil

7
不完美:它会在新内容之前简短地显示旧内容。
洛朗

3
如果要使用上面的示例清空模态,则应该能够remoteData在行之前或之后添加以下内容:$(this).empty()
jgillman 2013年

11
您不应该使用$(this).empty()。该remote选项将远程数据加载到嵌套<div class="modal-content">元素中。使用$('.modal-content', this).empty();代替。
加文2014年

50

对于Bootstrap 3.1,您将要删除数据并清空modal-content对话框而不是整个对话框(3.0),以避免在等待远程内容加载时闪烁。

$(document).on("hidden.bs.modal", function (e) {
    $(e.target).removeData("bs.modal").find(".modal-content").empty();
});

如果您使用的是非远程模态,那么上面的代码当然会在关闭后删除其内容(错误)。您可能需要向这些模式(如.local-modal类)添加一些内容,以使它们不受影响。然后将上面的代码修改为:

$(document).on("hidden.bs.modal", ".modal:not(.local-modal)", function (e) {
    $(e.target).removeData("bs.modal").find(".modal-content").empty();
});

在远程页面上,请确保您没有加载引导程序或jquery库。它将杀死所有引用,并为您留下一个空的模态。
2014年

这对我不起作用。这是我的代码正在工作:$(document).on(“ hidden.bs.modal”,“ .modal”,function(e){if(!$(e.target).is(“。local-modal “)){$(e.target).removeData(” bs.modal“)。find(”。modal-content“)。empty();}));
凯文(Kevin)

当我使用$(e.target).removeData("bs.modal").find(".modal-content").empty();它时,就像我的模态以某种方式被隐藏了,只出现了灰色的叠加层。
Axel

30

谢谢。我开始对boostrap.js进行修改,但是您的答案是一种快速,干净的解决方法。这就是我最终在代码中使用的内容。

$('#modal-item').on('hidden', function() {
    $(this).removeData('modal');
});

21

可接受的答案对我不起作用,因此我使用JavaScript做到了。

<a href="/foo" class="modal-link">
<a href="/bar" class="modal-link">

<script>
$(function() {
    $(".modal-link").click(function(event) {
        event.preventDefault()
        $('#myModal').removeData("modal")
        $('#myModal').modal({remote: $(this).attr("href")})
    })
})

14

这适用于Bootstrap 3 FYI

$('#myModal').on('hidden.bs.modal', function () {
  $(this).removeData('bs.modal');
});

7

我的项目是在Yii中构建的,并使用Bootstrap-Yii插件,因此,仅当您使用Yii时此答案才有意义。

上面的修复程序确实有效,但是仅在第一次显示模态之后。第一次出现空白。我认为那是因为在我启动代码后,Yii调用了模式的hide函数,从而清除了我的启动变量。

我发现将removeData调用放在启动模式的代码之前就可以了。所以我的代码是这样构造的...

$ ("#myModal").removeData ('modal');
$ ('#myModal').modal ({remote : 'path_to_remote'});

5

在Bootstrap 3.2.0中,“ on”事件必须在文档上,并且您必须清空模式:

$(document).on("hidden.bs.modal", function (e) {
    $(e.target).removeData("bs.modal").find(".modal-content").empty();
});

在Bootstrap 3.1.0中,“ on”事件可以出现在主体上:

$('body').on('hidden.bs.modal', '.modal', function () {
    $(this).removeData('bs.modal');
});

在Bootstrap 3.1中,3.2解决方案是唯一对我来说正常工作的方法-使用body方法,我在modal上的一些事件被取消了。
StuartQ 2014年

3

为什么不使它与BS 3更通用?只需使用“ [something] modal”作为模态DIV的ID。

$("div[id$='modal']").on('hidden.bs.modal',
    function () {
        $(this).removeData('bs.modal');
    }
);

2

我唯一的工作选择是:

$('body').on('hidden.bs.modal', '#modalBox', function () {
    $(this).remove();
});

我使用Bootstrap 3,并且有一个名为的函数popup('popup content') ,该函数 会附加模式框html。


2
这是BS 3.3.6对我唯一有效的方法。也使用把手模板。我建议使用文档而不是正文。
dbinott '16

1

添加一个$(this).html(''); 也可以清除可见数据,并且效果很好


1

如果提供了远程URL,则将通过jQuery的load方法加载一次内容,并将其注入到.modal-content div中。如果您使用的是data-api,则可以选择使用href属性指定远程源。下面是一个示例

$.ajaxSetup ({
    // Disable caching of AJAX responses
    cache: false
});

1

我添加了这样的内容,因为显示了较旧的内容,直到出现新内容为止,.modal-content内带有.html('')可以清除其中的HTML,希望对您有所帮助

$('#myModal').on('hidden.bs.modal', function () {
   $('#myModal').removeData('bs.modal');
   $('#myModal').find('.modal-content').html('');
});

这是迄今为止我找到的最简单的工作答案。答案没什么复杂的,几行代码且易于解释。第一次完美工作,却一团糟。
Tarquin

0

我写了一个简单的代码片段来处理模态的刷新。基本上,它将被单击的链接存储在模态数据中,并检查它是否与单击的链接相同,是否删除了模态数据。

var handleModal = function()
{
    $('.triggeringLink').click(function(event) {
        var $logsModal = $('#logsModal');
        var $triggeringLink = $logsModal.data('triggeringLink');

        event.preventDefault();

        if ($logsModal.data('modal') != undefined
            && $triggeringLink != undefined
            && !$triggeringLink.is($(this))
        ) {
            $logsModal.removeData('modal');
        }

        $logsModal.data('triggeringLink', $(this));

        $logsModal.modal({ remote: $(this).attr('href') });
        $logsModal.modal('show');
    });
};

0

对于Bootstrap 3,我在modal.js中进行了更改:

$(document)
  .on('show.bs.modal',  '.modal', function () { $(document.body).addClass('modal-open') })
  .on('hidden.bs.modal', '.modal', function () { $(document.body).removeClass('modal-open'); })

$(document)
  .on('show.bs.modal',  '.modal', function () { $(document.body).addClass('modal-open') })
  .on('hidden.bs.modal', '.modal', function () { 
    $(this).removeData('bs.modal').empty()
    $(document.body).removeClass('modal-open')
  })

(为清楚起见增加了额外的间距)

通过在模式容器上调用empty()并删除数据,可以防止旧的模式内容出现任何不必要的闪烁。


0
        $('#myModal').on('hidden.bs.modal', function () {
            $(this).removeData('modal');
        });

这对我有用。



0
$('body').on('hidden.bs.modal', '.modal', function () {
       $("#mention Id here what you showed inside modal body").empty()
});

您想清空哪个html元素(div,span等等)。


0

这对我有用:

情态的

<div class="modal fade" id="searchKaryawan" tabindex="-1" role="dialog" aria-labelledby="SearchKaryawanLabel" aria-hidden="true"> <div class="modal-dialog">
<div class="modal-content">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    <h4 class="modal-title" id="SearchKaryawanLabel">Cari Karyawan</h4>
  </div>
  <div class="modal-body">
    <input type="hidden" name="location">
    <input name="cariNama" type="text" class="form-control" onkeyup="if (this.value.length > 3) cariNikNama();" />
    <div class="links-area" id="links-area"></div>
  </div>
  <div class="modal-footer">
  </div>
</div> </div></div>

脚本

<script type="text/javascript">$('body').on('hidden.bs.modal', '.modal', function () {  $(".links-area").empty() }); </script>

链接区域是我放置数据并需要清除的区域


0

@merv接受的答案的扩展版本。它还检查是否从远程源加载了被隐藏的模式,并清除了旧内容以防止其闪烁。

$(document).on('hidden.bs.modal', '.modal', function () {
  var modalData = $(this).data('bs.modal');

  // Destroy modal if has remote source – don't want to destroy modals with static content.
  if (modalData && modalData.options.remote) {
    // Destroy component. Next time new component is created and loads fresh content
    $(this).removeData('bs.modal');
    // Also clear loaded content, otherwise it would flash before new one is loaded.
    $(this).find(".modal-content").empty();
  }
});

https://gist.github.com/WojtekKruszewski/ae86d7fb59879715ae1e6dd623f743c5


-1

在Bootstrap版本3.3.2上测试

  $('#myModal').on('hide.bs.modal', function() {
    $(this).removeData();
  });

1
这是一个糟糕的解决方案。呼唤.removeData()不带参数的将告诉jquery删除附加到该元素的所有数据。至于任择议定书的问题而言,.removeData('bs.modal')还是.removeData('modal')就足够了,是非常安全的。
朱利安·保罗·达亚格

-4

祝你好运:

$('#myModal').on('hidden.bs.modal', function () {
    location.reload();
});

2
这没用。重新加载页面不是解决方案。
dbinott '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.