Colorbox (which uses live) without restoring after jQuery ajax call

I have a list of items that I load through ajax (using jQuery.load ()). Each of these elements has a link (edit) associated with it, in which lightboxes (using colorbox) slightly change their shape. When the lightbox is closed, I use callback onClosed to reload the ajax list to display and the changes made during editing.

The colorbox call looks like this:

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

My list is as follows:

 <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> 

I looked at the colorbox source code and saw that jquery live() used to complete the binding. There he is:

 $('.' + 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; } }); 

You can see how colorbox works by binding to the "boxElement", which is the class it creates, is called "cboxElement". Before livebox (live box) adds this class (cboxElement) to all elements matching the selector (.colorbox in my example), then binds to this new class.

So I thought that if I put the colorbox bind outside the ajaxed content, it would bind to the links after I replaced the div #featureList with ajax, since live () should communicate with the elements "now or in the future", But this happens not because it binds to .cboxElement, not to .colorbox, so when ajax reloads colorbox, it does not re-add the .cboxElement class to the elements.

I tried calling $ .fn.colorbox.init () in ajax content to get colorbox to re-add the .cboxElement class to the elements, but that did not affect it. (I do something similar when working with shadowbox, but it doesn't seem to work the same for colorbox.)

So, I tried to put all the colorbox code inside the ajax content. When I do this, the colorbox binding is stacking / chaining. So the second time I call it, I get two colorboxes (and you need to press the close button twice to return to the main screen). The third time I get three. This is because when I call colorbox again, it adds the .cboxElement class, making the old live () binds active again, and also adds the ANOTHER live () binding to it. I tried to clear the .live () bindings by calling .die () first, but for some reason this did not work.

I found a couple of related entries, but none of them solved this problem, since colorbox already uses live ():
Problem with jQuery Colorbox
jQuery AJAX table per page, but now color column overlays no longer work

Any other ideas? I'm really at a standstill. I feel like I need to switch to a different lightbox, but overall I like the colorbox, and it works great throughout the site until this problem has arisen.

Thanks!!!

EDIT:

So, in this case, my problem was that my infrastructure ( Yii ) included a duplicate colorbox script on every AJAX call, which caused the problem. So watch this!

For everyone who has problems that do not face the duplicate script problem, I was: @Relic points out below, you can partly β€œfix” some problems by doing your own jQuery delegate () bind, which makes a β€œdirect call” to colorbox , instead of relying on the default binding, the colorbox defaults to live() . I would do this for my case:

 $(document).delegate("#features a", "click", function (event) { // $.colorbox() call } 
+4
source share
3 answers

The problem seems to be related to what I did not notice at first, and therefore did not ask the question. I edited the question to reflect this new information.

My problem was that the AJAX answer was multi-connected and included the colorbox script several times. The Yii Framework helper widget that I used to include the script also includes jQuery and Colorbox in the EVERY TIME response. Yii has no way to determine if the required scripts (e.g. jQuery) were already included in the main page (a typical stateless HTTP problem), so it includes it in partial AJAX rendering every time.

I solved this problem without using Yii Widget to bind Colorbox for every renderPartial Ajax call. I just enable color snapping on the parent page, so there is no JS in the Ajax content.

0
source

First of all, you should not use .live() , which is deprecated. Instead, learn how to use .delegate() . You will find that this is a much more powerful listener and will help solve your problem.

When loading the page, the DOM is first ready, and the color block is initialized for the AJAX selector to call up a new fragment of the page with some DOM element, which is in the list of column selectors, but is not noticed because it is loaded on the page after the selector has been read by javascript.

Try the following: as it looks body #main for all existing and new 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});}); 

EDIT for ".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 }); }); 

Yes, a big change, I know, but the fact is that the 'on' method can also be used as a "binding", so it's cool.

+4
source

I solved this in a fairly simple way.

If you send an ajax response (usually a javascript response) - attach the normal colorbox binding code (as elsewhere) in this answer.

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

append this in js response from the server. it worked for me.

+1
source

All Articles