colorbox (который использует live) не перепривязывается после вызова jQuery ajax - PullRequest
4 голосов
/ 22 августа 2010

У меня есть список элементов, которые я загружаю через ajax (используя .load ()) в jQuery.Каждый из этих элементов имеет ссылку (изменить) рядом с ним, что лайтбоксы (с помощью colorbox) немного формы редактирования.Когда лайтбокс закрыт, я использую обратный вызов onClosed для перезагрузки списка ajax для отображения и изменений, внесенных во время редактирования.

Вызов colorbox выглядит следующим образом:

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

Мой список выглядит следующим образомthis:

<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".Перед тем, как livebox (bind colorbox) добавляет этот класс (cboxElement) ко всем элементам, соответствующим селектору (в моем примере - .colorbox), затем связывается с этим новым классом.

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

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

Итак, я попытался поместить весь код colorbox в содержимое ajax.Когда я делаю это, привязки colorbox складываются / сцепляются.Итак, во второй раз, когда я это называю, я получаю два цветовых окна (и мне приходится дважды нажимать кнопку «Закрыть», чтобы вернуться на главный экран).В третий раз я получаю три.Это связано с тем, что когда я снова вызываю colorbox, он добавляет класс .cboxElement, делая старое связывание live () снова активным, а также добавляет ДРУГОЕ связывание live () с ним.Я попытался очистить привязки .live (), сначала вызвав .die (), но по какой-то причине это не сработало.

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

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

Спасибо !!!

РЕДАКТИРОВАТЬ:

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

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

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

Ответы [ 3 ]

4 голосов
/ 24 января 2012

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

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

1 голос
/ 24 августа 2010

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

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

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

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

0 голосов
/ 26 августа 2010

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

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

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

...