$(window).scroll(...) 是 运行 即使模板在流星中被破坏

$(window).scroll(...) is running even if the template is destroyed in meteor

我有两个单独的模板,在两个模板(渲染)中我都在做 $(window).scroll() 但是转到另一个模板, $(window).scroll() 是 运行 来自之前和当前的模板。

代码片段如下:

dashboard1.js

Template.dashboard1.rendered = function(){
    $(window).scroll(function() {
        console.log('dashboard1 scroll');
        //... doing pagination and sticky element for dashboard1
    });
}

Template.dashboard1.destroyed = function(){
    console.log('dashboard1 destroyed');
}

dashboard2.js

Template.dashboard2.rendered = function(){
    $(window).scroll(function() {
        console.log('dashboard2 scroll');
        //... doing pagination and sticky element for dashboard2
    });
}

Template.dashboard2.destroyed = function(){
    console.log('dashboard2 destroyed');
}

控制台:

dashboard1 destroyed
dashboard2 scroll
dashboard1 scroll
dashboard2 scroll
dashboard1 scroll
dashboard2 scroll

但如果我刷新浏览器,则它仅来自当前模板。

为什么会这样?解决这个问题的方法是什么。

在 Meteor 中销毁模板将执行有关模板渲染引擎 (Blaze) 的内部清理,并且会注销通过模板事件映射声明的事件,但不会注销全局 window 事件流星不知道。

使用 $.ononRendered 生命周期事件回调中注册自定义全局事件后,您需要使用 $.offonDestroyed 回调中注销它。

您可以使用此模式注册和注销处理程序:

Template.dashboard1.onRendered(function(){
  this.scrollHandler = function(){
    // you can use the this keyword here to reference the template instance
    console.log("dashboard1 scroll");
    //... doing pagination and sticky element for dashboard1
  }.bind(this);
  $(window).on("scroll" ,this.scrollHandler);
});

Template.dashboard1.onDestroyed(function(){
  $(window).off("scroll", this.scrollHandler);
  console.log("dashboard1 destroyed");
});

通过附加一个 this-bound 函数作为模板实例的 属性,您可以在事件处理程序中执行模板实例特定的逻辑。

当模板被销毁时,您需要手动删除监听器。

var scrollHandler = function() {
  console.log('dashboard1 scroll');
}

Template.dashboard1.rendered = function() {
  $(window).scroll(scrollHandler);
}

Template.dashboard1.destroyed = function() {
  $(window).off("scroll", scrollHandler);
  console.log('dashboard1 destroyed');
}