Colorbox (который использует live), не восстанавливая после jQuery ajax call

У меня есть список элементов, которые я загружаю через ajax (используя jQuery.load()). У каждого из этих элементов есть связанная с ним ссылка (edit), в которой лайтбоксы (с помощью colorbox) немного изменяют форму. Когда лайтбокс закрыт, я использую callback 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 href="/template/featureLightbox?template_id=000000000008&delta=0">Edit</a>)</li>
 <li id="item_000000000008+1">Element 2 (<a href="/template/featureLightbox?template_id=000000000008&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". Перед тем, как livebox (live box) добавит этот класс (cboxElement) ко всем элементам, соответствующим селектору (.colorbox в моем примере), затем привязывается к этому новому классу.

Так подумал, что если бы я поместил colorbox bind за пределы ajaxed контента, он привязал бы к ссылкам после того, как я заменил div #featureList на ajax, так как live() должен связываться с элементами "сейчас или в будущем", Но это происходит не потому, что он привязывается к .cboxElement, а не к .colorbox, поэтому, когда ajax перезагружает colorbox, он не повторно добавляет класс .cboxElement к элементам.

Я попытался вызвать $.fn.colorbox.init() в контенте ajax, чтобы получить colorbox для повторного добавления класса .cboxElement к элементам, но это не повлияло. (Я делаю что-то подобное при работе с shadowbox, но, похоже, он не работает одинаково для colorbox.)

Итак, я попытался поместить весь код colorbox внутри содержимого ajax. Когда я это делаю, привязка colorbox - это укладка/цепочка. Поэтому во второй раз, когда я это называю, я получаю два colorboxes (и вам нужно дважды нажать кнопку "закрыть", чтобы вернуться на главный экран). В третий раз я получаю три. Это связано с тем, что когда я вызываю colorbox снова, он добавляет класс .cboxElement, заставляя старые live() binds активны снова, а также добавляет к нему привязку ANOTHER live(). Я попытался очистить привязки .live(), вызвав сначала .die(), но по какой-то причине это не сработало.

Я нашел пару связанных записей, но ни один из них не решил эту проблему, поскольку colorbox уже использует live(): Проблема с jQuery Colorbox таблица jQuery AJAX на страницу, но теперь наложения цветных колонок больше не работают

Любые другие идеи? Я действительно в тупике. Я чувствую, что мне нужно переключиться на другой лайтбокс, но в целом мне нравится colorbox, и он отлично работает повсюду на сайте, пока эта проблема не возникла.

Спасибо!!!

ИЗМЕНИТЬ:

Итак, в этом случае моя проблема заключалась в том, что моя инфраструктура (Yii) включала дубликат colorbox script on каждый вызов AJAX, что вызывало проблему. Поэтому следите за этим!

Для всех, у кого есть проблемы, которые не сталкиваются с проблемой duplicate- script, я был: @Relic указывает ниже, вы можете отчасти "устранить" некоторые проблемы, выполнив свои собственные jQuery delegate() bind, который выполняет "прямой вызов" colorbox, вместо того, чтобы полагаться на привязку по умолчанию colorbox по умолчанию live(). Я бы это сделал для моего случая:

$(document).delegate("#features a", "click", function (event) { // $.colorbox() call }
3 ответа

Проблема, похоже, связана с тем, что я не заметил вначале, и поэтому не задал вопрос. Я отредактировал вопрос, чтобы отразить эту новую информацию.

Моя проблема заключалась в том, что ответ AJAX был многосвязным и включал colorbox script несколько раз. Виджет-помощник Yii Framework, который я использовал для включения script, также включает jQuery и Colorbox в ответе КАЖДОЕ ВРЕМЯ. У Yii нет способа определить, были ли требуемые скрипты (например, jQuery) уже включены в основную страницу (типичная проблема HTTP без учета состояния), поэтому она включает ее в частичный рендеринг AJAX каждый раз.

Я решил эту проблему, не используя Yii Widget для привязки Colorbox для каждого вызова renderPartial Ajax. Я просто включаю привязку к цвету на родительской странице, поэтому в содержимом Ajax нет JS.


Прежде всего, вы не должны использовать .live(), который устарел. Вместо этого узнайте, как использовать .delegate(). Вы обнаружите, что это гораздо более мощный слушатель и поможет решить вашу проблему.

При загрузке страницы сначала DOM готов, и цветной блок инициализируется для селектора 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' также может использоваться как "привязка", так что это классно.


Я решил это довольно простым способом.

Если вы отправляете ответ ajax (как правило, ответ на javascript) - присоедините нормальный код привязки colorbox (как и в любом месте) в этом ответе.

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

присоедините это в ответ js от сервера. это сработало для меня.

licensed under cc by-sa 3.0 with attribution.