Я не могу получить Backbone.js события, которые запускаются, когда представление находится внутри Fancybox

#javascript #backbone.js #fancybox #lightbox

#javascript #backbone.js #fancybox #лайтбокс

Вопрос:

У меня есть базовое представление, которое отображается в Fancybox. Я могу щелкнуть по тегу привязки, и он будет работать, но события в представлении Backbone не будут запускаться. У меня была такая же проблема с ShadowBox и другим лайтбоксом, который я не могу вспомнить. Есть мысли?

 var LightboxItemView = Backbone.View.extend({
    className : 'lighbox-item',

    events : {
        "click .lightbox-preview" : "visitItemPage"
    },

    initialize : function() {
        _.bindAll(this, "render");
        this.render();
    },

    visitItemPage : function() {
        console.log('visiting time');
    },

    render : function() {
        var graphicPreview = $('<img>');
        graphicPreview.addClass('lightbox-preview');
        graphicPreview.attr('src', this.model.get('url_m'));

        var lbContent = $('<div></div>');
        lbContent.attr("id", 'lb'   this.model.get('id'));
        lbContent.append(graphicPreview);

        var lbHider = $('<div></div>');
        lbHider.css("display", "none");
        lbHider.append(lbContent);

        $(this.el).append(lbHider);
        return this;
    }
});
 

Ответ №1:

Библиотеки лайтбоксов перемещают ваш элемент с того места, куда вы его вставили в DOM. Обычно они создают новый контейнер, помещают ваш элемент внутрь, а затем отображают контейнер поверх всего остального.

Во-первых, используйте Firebug или Инспектор в вашем браузере, чтобы посмотреть, что именно делает библиотека. Затем вы можете использовать обычные обработчики событий в jQuery, чтобы заставить его работать http://api.jquery.com/bind /.

 initialize: function() {
  $('<your-element-in-the-overlay-box> a').click(handler)
}
 

Магистральные события не работают, потому что элемент больше не находится внутри вашего магистрального представления el .

Комментарии:

1. Спасибо. Я думал об этом подходе, но надеялся найти что-то, связанное с обработчиками событий Backbone, только по одной причине, кроме согласованности. Кроме того, я не понимаю причины, по которой это не работает. Разве «.lightbox-preview», с которым связано событие, не находится внутри «lbHider», который является el основного представления? Запутался!

Ответ №2:

Я использую Facebox для аналогичного эффекта лайтбокса и сталкиваюсь с той же проблемой. После некоторой отладки и переключения оказывается, что делегаты событий действительно работают, но вы должны отобразить свое представление ПОСЛЕ того, как вы запустили facebox.

В моем случае у меня есть многоразовое представление, которое при необходимости скрывается / показывается. Я должен был сделать это для метода show (), который будет вызываться другим представлением для отображения :

 show: function(model) {
  $.facebox(this.el);
  // now render my element
  this.model = model;
  $(this.el).html( ... from template ... )
}
 

По сути, если вам нужно повторно отобразить свое представление, сделайте это после вызова facebox / lightbox, чтобы события были правильно делегированы представлению.

Ответ №3:

Я согласен с тем, что сказала дира, но я не думаю, что это исключает ваше дальнейшее использование обработки событий Backbone. Почему бы просто не привязать Fancybox к div, окружающему div, который является el для вашего представления?

Мне удалось заставить это работать в jsFiddle, за исключением того, что у него постоянно возникают проблемы с загрузкой либо Backbone.js или код Fancybox удаленно. Так что это довольно плохой пример, если только вы не хотите перезагружать его полдюжины раз. Вставьте код на страницу, содержащую все эти файлы, и я обещаю, что он будет работать, хотя я действительно тестировал его:

Вот HTML-код:

 <div style="display:none">
  <div id="popupView">
    This is some example stuff for the Fancybox. 
    It could have been generated by a template just as easily. 
    <a id="clickMe">Click Here!</a>
  </div>
</div>

<p>
  <a id="popupTrigger" href="#popupView">
    Popup a Fancybox containing the results</a>
</p>
 

И вот JavaScript для этого:

 $(document).ready(function () {
    var TestView = Backbone.View.extend({
        el: "#popupView",

        events: {
            "click #clickMe": "clickMe"
        },

        clickMe: function () {
            alert("You clicked it! You seem like that type.");
        }
    });

    var view = new TestView({
        "el": "#popupView"
    });

    view.render();
    $("#popupTrigger").fancybox();
});
 

Примечание: Этот код работает, несмотря на то, что нигде нет дополнительных оберток. Вы можете нажать на ссылку в Fancybox, и соответствующий код в представлении будет запущен.

Комментарии:

1. Это делает это. Я все еще не понимаю, почему, но это нормально.