Ember.js恢复历史记录滚动,重置滚动链接

Bou*_*uke 9 scroll ember.js html5-history

Daniel F Pupius将问题描述为:

很多网站都错了,这真的很烦人.当用户使用浏览器的前进或后退按钮导航时,滚动位置应与上次在页面上的位置相同.这有时在Facebook上正常工作,但有时却没有.Google+似乎总是失去你的滚动位置.

因此,在浏览新页面时,已经有很多关于将滚动条重置到页面顶部的问题.Ember.js的Cookbook还展示了如何融入Route.activate:

export default Ember.Mixin.create({
  activate: function() {
    this._super();
    window.scrollTo(0,0);
  }
});
Run Code Online (Sandbox Code Playgroud)

然而,这只能解决问题的一半.当用户使用后退/前进按钮时,滚动位置将不会恢复,而只是重置.

有很多尝试解决这个问题,很多只是将滚动位置存储在Ember.Controller实例中,例如在本文中.然而,这只是部分解决方案.如果多次使用控制器,则仅保留单个滚动状态.

如何保留恢复旧滚动状态的默认浏览器实现?因此,如果Route.activate从html5历史状态更改触发,什么都不做?

Jer*_*yTM 14

我刚刚在自己的应用程序中解决了这个问题.

如果您只想在需要它的地方使用它,只需使用mixin:

ember g mixin remember-scroll

然后在mixins/remember-scroll.js,替换为:

import Ember from 'ember';

export default Ember.Mixin.create({

  scrollSelector: window,

  activate: function() {
    this._super.apply(this, arguments);
    var self = this;
    if( this.get('lastScroll') ){

      Ember.run.next(function(){
        Ember.$(self.scrollSelector).scrollTop(self.get('lastScroll'));
      });

    } else {
      Ember.$(this.scrollSelector).scrollTop(0);
    }
  },

  deactivate: function() {
    this._super.apply(this, arguments);
    this.set('lastScroll',Ember.$(this.scrollSelector).scrollTop());
  },

});
Run Code Online (Sandbox Code Playgroud)

如果您希望它自动混合到所有路线,请执行以下操作.

在Ember CLI中,创建一个新的初始化程序.

ember g initializer remember-scroll

然后initializers/remember-scroll.js,用以下代码替换代码:

import Ember from "ember";

var rememberScroll = Ember.Mixin.create({

  scrollSelector: window,

  activate: function() {
    this._super.apply(this, arguments);
    var self = this;
    if( this.get('lastScroll') ){

      Ember.run.next(function(){
          Ember.$(self.scrollSelector).scrollTop(self.get('lastScroll'));
      });

    } else {
      Ember.$(this.scrollSelector).scrollTop(0);
    }
  },

  deactivate: function() {
    this._super.apply(this, arguments);
    this.set('lastScroll',Ember.$(this.scrollSelector).scrollTop());
  },

});

export function initialize(/* container, application */) {
  Ember.Route.reopen(rememberScroll);
}

export default {
  name: 'remember-scroll',
  initialize: initialize
};
Run Code Online (Sandbox Code Playgroud)

如果您使用初始化程序版本,则可以删除上面的第一个mixin.

这应该会导致您的所有路线都记住最后一个滚动位置(如果您以前曾经在那里),并在您返回时应用它.

虽然我建议不要把它放在所有路线中,因为如果自从他们最后一次经过很长时间后,用户可能不会期望返回到先前的滚动位置.