滚动时解除绑定事件 - 推荐?

时间:2013-01-07 12:07:54

标签: jquery backbone.js marionette backbone-views backbone-events

我的网站建立在骨干网上。它具有基于订阅源的UI,这意味着在订阅源中通常会显示大量内容。粗略地说,大约30个事件绑定到每个项目。

在向下滚动几页后,它变得缓慢。

取消绑定已滚出的项目是否有意义,并在滚动时再次绑定?

  • 如果是这样,一些帮助(示例代码/指向资源的指针会很棒)
  • 是否有任何导致缓慢的事情?

1 个答案:

答案 0 :(得分:2)

很难说缓慢是因为事件处理程序,还是因为浏览器无法处理页面上大量的DOM节点,或者其他任何原因。

这是一个快速解决方案,用于取消未在当前视口中的视图的事件。它不完全适合生产,但应该帮助您测试事件处理程序是否是性能问题的原因。

Working JSFiddle here,同时检查浏览器控制台)

var View = Backbone.View.extend({

  onScroll: function() {

    var wasInView = this.isInView;
    var isInView = this.checkIsInView();

    if(wasInView === true) {
      if(!isInView) {
         this.undelegateEvents(); 
      }
    } 
    else if(wasInView === false) {
      if(isInView) {
        this.delegateEvents();
      }
    }
    else {
      //first pass
      if(!isInView) {
        this.undelegateEvents();
      }
    }

    this.isInView = isInView;
  },

  checkIsInView: function() {
    var $el = this.$el,
        top = $el.offset().top,
        bottom = top + $el.height(),
        windowTop = $(window).scrollTop(),
        windowBottom = windowTop + $(window).height();

    return ((bottom <= windowBottom) && (top >= windowTop));
  },

  render: function () {

    //rendering code here...

    if(!this.lazyScroll) {
      //wait for scroll events to stop before triggering scroll handler
      this.lazyScroll = _.debounce(_.bind(this.onScroll, this), 50);
      $(window).bind('scroll', this.lazyScroll)
               .bind('resize', this.lazyScroll); 
    }

    return this;
  },

  remove: function() {
    if(this.lazyScroll) {
      $(window).unbind('scroll', this.lazyScroll)
               .unbind('resize', this.lazyScroll); 
      delete this.lazyScroll;
    }
    Backbone.View.prototype.remove.apply(this, arguments);
  }
});