平滑滚动角度2 [英] Smooth scroll angular2
问题描述
我在使平滑滚动服务在角度2上工作时遇到麻烦.在角度2团队获得与$ anchorScroll angular2等效的工作之前,是否可以进行平滑滚动或普通锚滚动的服务?
I am having trouble getting a smooth scroll service to work in angular 2. Are there any services for smooth scrolling, or plain anchor scrolling, that might work until the angular 2 team gets the $anchorScroll angular2 equivalent working?
到目前为止,我刚刚尝试过:
So far I have just tried:
在父div上设置* ngFor循环增量ID
Setting *ngFor loop incremental id on a parent div
[attr.id]="'point' + i"
在传递了ID的按钮上调用scrollto
Calling a scrollto on a button with the id passed
<button
type="button"
class="btn btn-lg btn-default "
(click)="smoothScroll('point'+i)">
Scroll to point
</button>
在相关的组件中,我试图实现一个普通的js平滑滚动功能
And in the associated component I am trying to implement a plain js smooth scroll function
smoothScroll(eID) {
var startY = currentYPosition();
var stopY = elmYPosition(eID);
var distance = stopY > startY ? stopY - startY : startY - stopY;
if (distance < 100) {
scrollTo(0, stopY); return;
}
var speed = Math.round(distance / 100);
if (speed >= 20) speed = 20;
var step = Math.round(distance / 25);
var leapY = stopY > startY ? startY + step : startY - step;
var timer = 0;
if (stopY > startY) {
for (var i = startY; i < stopY; i += step) {
setTimeout(this.win.scrollTo(0, leapY), timer * speed);
leapY += step; if (leapY > stopY) leapY = stopY; timer++;
} return;
}
for (var i = startY; i > stopY; i -= step) {
setTimeout(this.win.scrollTo(0,leapY), timer * speed);
leapY -= step; if (leapY < stopY) leapY = stopY; timer++;
}
}
function currentYPosition() {
// Firefox, Chrome, Opera, Safari
if (self.pageYOffset) return self.pageYOffset;
// Internet Explorer 6 - standards mode
if (document.documentElement && document.documentElement.scrollTop)
return document.documentElement.scrollTop;
// Internet Explorer 6, 7 and 8
if (document.body.scrollTop) return document.body.scrollTop;
return 0;
}
function elmYPosition(eID) {
var elm = document.getElementById(eID);
var y = elm.offsetTop;
var node = elm;
while (node.offsetParent && node.offsetParent != document.body) {
node = node.offsetParent;
y += node.offsetTop;
} return y;
}
我还试图允许访问this._win.scrollTo的窗口,该窗口来自窗口提供程序服务
I'm also trying to give access to the window for the this._win.scrollTo which is coming from a window provider service
import {Injectable, Provider} from 'angular2/core';
import {window} from 'angular2/src/facade/browser';
import {unimplemented} from 'angular2/src/facade/exceptions';
function _window(): Window {
return window
}
export abstract class WINDOW {
get nativeWindow(): Window {
return unimplemented();
}
}
class WindowRef_ extends WINDOW {
constructor() {
super();
}
get nativeWindow(): Window {
return _window();
}
}
export const WINDOW_PROVIDERS = [
new Provider(WINDOW, { useClass: WindowRef_ }),
];
**编辑 --------------------- **
** EDIT ---------------------**
我将this.win.scrollTo更改为this.win.window.scrollTo,现在我得到的效果类似于angular1.x $ anchorscroll,其中滚动只是一个活泼的,而不是平滑的过渡,但是滚动是不顺利,并且出现以下异常错误.
I changed the this.win.scrollTo to this.win.window.scrollTo and now I am getting an effect similar to angular1.x $anchorscroll where the scroll is a snappy just instead of a smooth transition, but the scroll is not smooth and I am getting the following exception error.
更新
在我发现angular2做setTimeout有所不同之后,我不再遇到该错误,但是滚动仍然是瞬时的,而不是平滑的滚动.
I am no longer getting that error after finding out that angular2 is doing the setTimeout a bit differently, but the scroll is still instantaneous and not a smooth scroll.
我改变了
setTimeout(this.win.scrollTo(0, leapY), timer * speed);
到
setTimeout(() => this.win.scrollTo(0, leapY), timer * speed);
推荐答案
好吧,在我scratch了一下头之后,这是一个似乎可行的解决方案.
Alright, after scratching my head a little bit, here is a solution that seems to be working ok.
与以前一样,单击时声明了条件ID和带有scrollTo函数调用的按钮.
Same as before, I declared my conditional id and a button with the scrollTo function call when clicked.
现在,解决方案中只有两个文件是一项服务,该服务将帮助返回文档窗口和模板的组件.与上面的状态相比,窗口服务没有任何更改,但是为了得到一个好的答案,我将再次将其包括在内.
Now, there are only two files in the solution is a service that will help return the document window and the template's component. Nothing was changed in the window service from the state above but I will include it again for the sake of a good answer.
window.service.ts:向 https://gist.github.com/lokanx/cc022ee0b8999cd3b7f5喊叫为您提供帮助
window.service.ts : shout out to https://gist.github.com/lokanx/cc022ee0b8999cd3b7f5 for helping with this piece
import {Injectable, Provider} from 'angular2/core';
import {window} from 'angular2/src/facade/browser';
import {unimplemented} from 'angular2/src/facade/exceptions';
function _window(): Window {
return window
}
export abstract class WINDOW {
get nativeWindow(): Window {
return unimplemented();
}
}
class WindowRef_ extends WINDOW {
constructor() {
super();
}
get nativeWindow(): Window {
return _window();
}
}
export const WINDOW_PROVIDERS = [
new Provider(WINDOW, { useClass: WindowRef_ }),
];
app.component.ts
app.component.ts
import { bootstrap } from 'angular2/platform/browser';
import { Component } from 'angular2/core';
import {WINDOW, WINDOW_PROVIDERS} from './window.service';
@Component({
selector: 'my-app',
templateUrl: 'app.tpl.html',
providers: [WINDOW_PROVIDERS]
})
class AppComponent {
win: Window;
private offSet: number;
constructor(
private _win: WINDOW) {
this.win = _win.nativeWindow;
}
title = 'Ultra Racing';
things = new Array(200);
scrollTo(yPoint: number, duration: number) {
setTimeout(() => {
this.win.window.scrollTo(0, yPoint)
}, duration);
return;
}
smoothScroll(eID) {
var startY = currentYPosition();
var stopY = elmYPosition(eID);
var distance = stopY > startY ? stopY - startY : startY - stopY;
if (distance < 100) {
this.win.window.scrollTo(0, stopY); return;
}
var speed = Math.round(distance / 100);
if (speed >= 20) speed = 20;
var step = Math.round(distance / 100);
var leapY = stopY > startY ? startY + step : startY - step;
var timer = 0;
if (stopY > startY) {
for (var i = startY; i < stopY; i += step) {
this.scrollTo(leapY, timer * speed);
leapY += step; if (leapY > stopY) leapY = stopY; timer++;
} return;
}
for (var i = startY; i > stopY; i -= step) {
this.scrollTo(leapY, timer * speed);
leapY -= step; if (leapY < stopY) leapY = stopY; timer++;
}
}
}
function currentYPosition() {
// Firefox, Chrome, Opera, Safari
if (self.pageYOffset) return self.pageYOffset;
// Internet Explorer 6 - standards mode
if (document.documentElement && document.documentElement.scrollTop)
return document.documentElement.scrollTop;
// Internet Explorer 6, 7 and 8
if (document.body.scrollTop) return document.body.scrollTop;
return 0;
}
function elmYPosition(eID) {
var elm = document.getElementById(eID);
var y = elm.offsetTop;
var node = elm;
while (node.offsetParent && node.offsetParent != document.body) {
node = node.offsetParent;
y += node.offsetTop;
} return y;
}
bootstrap(AppComponent)
我创建了一个小插件来显示此示例的工作方式: 插件示例
I created a plunk to show this example working: Plunk Example
这篇关于平滑滚动角度2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!