颜色盒(使用live方法)在jQuery ajax调用后无法重新绑定

4
我有一个元素列表,通过ajax(使用jQuery的.load()方法)进行加载。每个元素旁边都有一个(编辑)链接,可以使用colorbox打开一个小的编辑表单。当关闭灯箱时,我使用onClosed回调重新加载ajax列表,以显示在编辑期间所做的任何更改。
colorbox调用如下:
$('.colorbox').colorbox({
  'iframe':true,
  'onClosed':function(){
    $("#featureList").load("/template/featureList","id="+$("#model_id").val());
  }
});

我的列表如下:

<div id="featureList">
  <ul id="features">
    <li id="item_000000000008+0">Element 1 (<a class="colorbox" href="/template/featureLightbox?template_id=000000000008&amp;delta=0">Edit</a>)</li>
    <li id="item_000000000008+1">Element 2 (<a class="colorbox" href="/template/featureLightbox?template_id=000000000008&amp;delta=1">Edit</a>)</li>
  </ul>
</div>

我查看了colorbox源代码,发现它使用jquery live()进行绑定。这是代码:
$('.' + boxElement).live('click', function (e) {
  if ((e.button !== 0 && typeof e.button !== 'undefined') || e.ctrlKey || e.shiftKey || e.altKey) {
    return true;
  } else {
    launch(this);   
    return false;
  }
});

您可以看到,colorbox的工作方式是绑定到“boxElement”,这是它创建的名为“cboxElement”的类。在live()绑定之前,colorbox会将此类(cboxElement)添加到与选择器(.colorbox在我的示例中)匹配的所有元素中,然后绑定到此新类。
因此,如果我将colorbox绑定放在ajax内容之外,它将绑定到我用ajax替换#featureList div后的链接,因为live()应该绑定到“现在或将来”的元素。但是它没有,因为它绑定到.cboxElement而不是.colorbox,因此当ajax重新加载时,colorbox不会重新向元素添加.cboxElement类。
我尝试在ajax内容中调用$.fn.colorbox.init()以使colorbox重新向元素添加.cboxElement类,但这没有任何效果。(当我处理shadowbox时会做类似的事情,但似乎对于colorbox不起作用。)
那么我尝试将所有的colorbox代码放在ajax内容中。当我这样做时,colorbox绑定会叠加/链接。所以第二次调用它时,我会得到两个colorbox(必须点击“关闭”按钮两次才能返回主屏幕)。第三次我得到三个。这是因为当我再次调用colorbox时,它会添加.cboxElement类,使旧的live()绑定再次激活,并且还会添加另一个live()绑定。我尝试通过首先调用.die()来清除.live()绑定,但由于某种原因它没有起作用。
我发现了一些相关的帖子,但由于colorbox已经在使用live(),所以它们都没有解决这个问题:
Problem with jQuery Colorbox
jQuery AJAX table to a page but now the colorbox overlays no longer work 还有其他想法吗?我真的很困惑。我觉得我应该换一个不同的lightbox,但总的来说,我喜欢colorbox,在站点的其他地方它也运行良好,直到出现这个ajax问题。
谢谢!

编辑:

所以,在这种情况下,我的问题是我的框架(Yii)在每次 AJAX 调用时都会包含重复的 colorbox 脚本,这导致了问题。因此,请注意!

对于所有遇到问题但不面临我遇到的重复脚本问题的人:如@Relic在下面指出的那样,你可以通过自己的 jQuery delegate() 绑定来解决一些问题,它直接调用 colorbox,而不是依赖于 colorbox 的默认 live() 绑定。对于我的情况,我会像这样进行调整:

$(document).delegate("#features a", "click", function (event) { // $.colorbox() call  }
3个回答

4
首先,您不应使用.live(),它已经过时。相反,学习如何使用.delegate()。您会发现这是一个更强大的监听器,可以帮助解决您的问题。
在页面加载时,最初的DOM已经准备就绪,并且针对选择器初始化了colorbox。当AJAX调用一个新的页面片段包含一些DOM元素时,这些元素在javascript读取选择器之后加载到页面中, 因此无法被注意到。
请尝试以下操作-它将监视body #main中的所有现有和新的a[rel='lightbox']
$("body #main").delegate("a[rel='lightbox']", "click", function (event) {
                    event.preventDefault();
                    $.colorbox({href: $(this).attr("href"),
                            transition: "fade",
                            innerHeight: '515px',
                            innerWidth: '579px',
                            overlayClose: true,
                            iframe: true,
                            opacity: 0.3});});

针对“.on()”进行编辑

$("body #main").on("click", "a[rel='lightbox']", function (event) {
                        event.preventDefault();
                        $.colorbox({href: $(this).attr("href"),
                                transition: "fade",
                                innerHeight: '515px',
                                innerWidth: '579px',
                                overlayClose: true,
                                iframe: true,
                                opacity: 0.3
                         });
});

是的,变化很大,我知道,但重点是'on'方法也可以用作'bind',所以这有点酷。


是的,delegate 是未来的趋势(据我所知,它更高效,而不是更“强大”)。从技术上讲,我从未使用过 live,colorbox 本身正在使用 live。我只是进行了常规的默认 .colorbox() 绑定。_我的_问题是由于多次包含 colorbox 脚本引起的(愚蠢的框架助手)。但是除了这个问题之外,像你说的将绑定委托给自定义的 $.colorbox() 调用对于新的 AJAX 内容应该可以正常工作。干杯 - thaddeusmt
1
所以... ...所有这些都说了... ..."on()"实际上是未来的方式。在我使用jQuery 1.7.1之前,我写了这篇文章。我会编辑我的答案以反映这些变化。(尽管它们很少)。 - Eric Hodonsky

1

我用一种非常简单的方法解决了这个问题。

如果你正在发送一个ajax响应(通常是javascript响应)- 在该响应中附加正常的colorbox绑定代码(就像在任何地方一样)。

$('.colorbox').colorbox({
  'iframe':true,
  'onClosed':function(){
    $("#featureList").load("/template/featureList","id="+$("#model_id").val());
  }
});

将此代码附加到您从服务器返回的JS响应中。这对我有效。


唉,这就是我需要处理多个彩色盒子的叠放和链接的地方。 - thaddeusmt

0

问题似乎与我一开始没有注意到的某些事情有关,因此我没有在我的问题中提及。我已经编辑了问题以反映这个新信息。

我的问题是 AJAX 响应多次绑定并多次包含 colorbox 脚本。我使用的 Yii 框架帮助器小部件也在每次响应中包括 jQuery 和 Colorbox。Yii 没有办法确定所需的脚本(如 jQuery)是否已经包含在主页面中(典型的无状态 HTTP 问题),因此它在每次 AJAX 部分呈现时都会将其包含进去。

我通过不使用 Yii Widget 在每个 Ajax 调用的 renderPartial 视图上进行 Colorbox 绑定来解决了这个问题。我只是在父级页面上包含 colorbox 绑定,这样 Ajax 内容就没有 JS。


你真的应该参考我上面的答案。 - Eric Hodonsky

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