更改视图时,Emberjs会滚动到顶部

时间:2012-10-29 11:11:19

标签: ember.js

当切换我的应用程序的主视图(重新连接应用程序控制器主出口的新路径)时,我希望页面滚动到顶部。否则,我导航到另一个类似页面的视图并且视口仍然在我离开的地方丢失时,有点奇怪。

我破解了一个解决方案,并想知道是否有更好的方法,或者是否有人有同样的事情。

这就是我的所作所为:

App.ApplicationController = Ember.Controller.extend({
  connectOutlet: function(){
    window.scrollTo(0, 0);
    this._super.apply(this, arguments);
  }
});

6 个答案:

答案 0 :(得分:19)

@ Baruch的解决方案很好,但是当我实现它时,我在应用程序状态中渲染了元素,并且在不需要时会导致scrollTop。

我发现这更有效,因为它只在路径变化上运行:

App.ApplicationController = Ember.Controller.extend({

  currentPathChanged: function () {
    window.scrollTo(0, 0);
  }.observes('currentPath')

});

答案 1 :(得分:9)

我用以下代码实现了这个目标:

Ember.Route.reopen({
  render: function(controller, model) {
    this._super();
    window.scrollTo(0, 0);
  }
});

答案 2 :(得分:7)

咖啡脚本:

Ember.Route.reopen
    activate: ->
      @_super()
      window.scrollTo(0, 0)

Javascript:

Ember.Route.reopen({
  activate: function() {
      this._super();
      window.scrollTo(0, 0);
  }
});

答案 3 :(得分:6)

您应该尝试扩展Ember.Route并在window.scrollTo回调中添加enter。然后,不是使用Ember的Route作为您的叶子路线,而是调用您的路线。extend(),这样当您输入路线/状态时,它们会自动向上滚动。 类似的东西:

// define your custom route and extend "enter"
var MyRoute = Em.Route.extend({
    enter: function(router) {
        // for now on, all the routes that extend this, 
        // will fire the code in this block every time
        // the application enters this state
        // do whatever you need to do here: scroll and whatnot
    }
});

App.Router = Em.Router.extend({
    enableLogging: true,
    location: 'hash',
    index: Em.Route.extend({
            route: '/',
            connectOutlets: function(router) {
                ...
            },
            // on your leaf routes, use your own custom route that 
            // does your scroll thing or whatever you need to do 
            home: MyRoute.extend({
                route: '/',
                connectOutlets: function (router, context) {
                     ...
                }
            }),
            // other routes...
       })
});

有意义吗?

答案 4 :(得分:1)

它现在是render(name, options),如果你专门调用渲染(即使用模态),你想将它传递给super()

Ember.Route.reopen({
  render: function(name, options) {
    if (name != null) {
      return this._super(name, options);
    } else {
      return this._super();
    }
  }
});

答案 5 :(得分:0)

Ember 3.12 + (从技术上讲,这是这里列出的3.20代码)

import EmberRouter from '@ember/routing/router';

const Router = EmberRouter.extend({
  init() {
    // call event everytime route changes
    this.on('routeDidChange', () => {
      this._super(...arguments);
      window.scrollTo(0, 0); // scrolls to top
    });
  }
});

Router.map(function () {
  // your mapping code goes here
});

export default Router;

3.12之前的版本(从技术上讲,这是3.4,但关键代码应该相同)

import EmberRouter from '@ember/routing/router';

const Router = EmberRouter.extend({
  didTransition() {
    this._super(...arguments);
    window.scrollTo(0, 0);
   }
});

Router.map(function () {
  // your mapping code goes here
});


export default Router;

我们已经在服务器时代处理了这个问题,我们发现最简单,最直接的方法是使用“路由转换”事件功能在router.js文件中配置一次。我们使用didTransition代替了routeDidChange在Ember 3.12中弃用了它。我在下面发布了两个示例。某些语法可能会略有不同,具体取决于您所使用的Ember版本,但是此核心代码应该相同。