平滑滚动角度2

Ale*_*x J 27 scroll smooth-scrolling typescript angular

我无法获得平滑的滚动服务以在角度2中工作.是否有任何平滑滚动或平滑锚定的服务,这可能会工作,直到角度2团队获得$ anchorScroll angular2等效工作?

到目前为止,我刚刚尝试过:

在父div上设置*ngFor循环增量ID

[attr.id]="'point' + i"
Run Code Online (Sandbox Code Playgroud)

在id传递的按钮上调用scrollto

<button 
     type="button" 
     class="btn btn-lg btn-default " 
     (click)="smoothScroll('point'+i)">
           Scroll to point
</button>
Run Code Online (Sandbox Code Playgroud)

在相关组件中,我试图实现一个简单的js平滑滚动功能

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;
}
Run Code Online (Sandbox Code Playgroud)

我也试图访问这个来自窗口提供者服务的this._win.scrollTo的窗口

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_ }),
];
Run Code Online (Sandbox Code Playgroud)

**编辑---------------------**

我将this.win.scrollTo更改为this.win.window.scrollTo现在我得到类似于angular1.x $ anchorscroll的效果,其中滚动是一个snappy而不是平滑过渡,但滚动不顺畅,我收到以下异常错误.

异常错误

UPDATE

在发现angular2以不同的方式执行setTimeout之后,我不再得到该错误,但滚动仍然是瞬时的而不是平滑的滚动.

我变了

  setTimeout(this.win.scrollTo(0, leapY), timer * speed);
Run Code Online (Sandbox Code Playgroud)

 setTimeout(() => this.win.scrollTo(0, leapY), timer * speed);
Run Code Online (Sandbox Code Playgroud)

Mer*_*ert 33

window对象中有一个方法叫做scrollTo().如果将行为设置为"平滑",则页面将处理平滑滚动.示例(滚动到页面顶部):

 window.scrollTo({ left: 0, top: 0, behavior: 'smooth' });
Run Code Online (Sandbox Code Playgroud)

并以后备为例:

    try 
    { 
     window.scrollTo({ left: 0, top: 0, behavior: 'smooth' });
     } catch (e) {
      window.scrollTo(0, 0);
      }
Run Code Online (Sandbox Code Playgroud)

  • Vivaldi和IE在测试期间不能正常工作.所以我使用了后备.try {window.scrollTo({left:0,top:0,behavior:'smooth'}); } catch(e){window.scrollTo(0,0); } (3认同)

Ale*_*x J 16

好吧,稍微刮了一下头后,这是一个似乎工作正常的解决方案.

与之前相同,我在单击时声明了条件id和带有scrollTo函数调用的按钮.

现在,解决方案中只有两个文件是一个有助于返回文档窗口和模板组件的服务.从上面的状态窗口服务中没有任何改变,但为了一个好的答案,我将再次包括它.

window.service.ts:大声呼喊https://gist.github.com/lokanx/cc022ee0b8999cd3b7f5来帮助这件作品

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_ }),
];
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

我创建了一个plunk以显示此示例正常工作: Plunk示例


小智 11

更简单的方法是使用这种polyfill:http: //iamdustan.com/smoothscroll/

  1. 安装方式为:npm install smoothscroll-polyfill
  2. 将它作为:require('smoothscroll-polyfill')导入polyfill.ts文件中.polyfill();
  3. 现在您可以使用scrollIntoView的行为选项:

    (document.querySelector('#'+ anchor)).scrollIntoView({behavior:'smooth'});

  • 我通过将它添加到 polyfills.ts 来让它工作:```import smoothscroll from 'smoothscroll-polyfill/dist/smoothscroll'; smoothscroll.polyfill();``` (2认同)