Helpex - Trao đổi & giúp đỡ Đăng nhập
29

Tôi đang gặp sự cố để dịch vụ cuộn mượt hoạt động ở góc 2. Có bất kỳ dịch vụ nào để cuộn trơn tru, hoặc cuộn neo đơn giản, có thể hoạt động cho đến khi nhóm angle 2 hoạt động tương đương với $ anchorScroll angle2 không?

Cho đến nay tôi mới thử:

Cài đặt * ngĐối với id tăng dần của vòng lặp trên div cha

[attr.id]="'point' + i"

Gọi một cuộn tới trên một nút có id được chuyển

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

Và trong thành phần được liên kết, tôi đang cố gắng triển khai chức năng cuộn trơn tru js đơn giản

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;
}

Tôi cũng đang cố gắng cấp quyền truy cập vào cửa sổ cho this._win.scrollTo đến từ dịch vụ của nhà cung cấp cửa sổ

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_ }),
];

** BIÊN TẬP ---------------------**

Tôi đã thay đổi this.win.scrollTo thành this.win.window.scrollTo và bây giờ tôi nhận được hiệu ứng tương tự như angle1.x $ anchorrscroll trong đó cuộn chỉ nhanh thay vì chuyển tiếp mượt mà, nhưng cuộn không mượt và Tôi nhận được lỗi ngoại lệ sau.

Cuộn mượt mà góc 2

CẬP NHẬT

Tôi không còn gặp lỗi đó nữa sau khi phát hiện ra rằng angle2 đang thực hiện setTimeout hơi khác một chút, nhưng cuộn vẫn ngay lập tức và không phải là cuộn trơn tru.

tôi đã thay đổi

  setTimeout(this.win.scrollTo(0, leapY), timer * speed);

đến

 setTimeout(() => this.win.scrollTo(0, leapY), timer * speed);
29 hữu ích 2 bình luận 55k xem chia sẻ
40

có một phương thức trong windowđối tượng được gọi scrollTo(). Nếu bạn đặt hành vi thành 'mượt mà', trang sẽ xử lý cuộn mượt mà. ví dụ (cuộn lên đầu trang):

 window.scrollTo({ left: 0, top: 0, behavior: 'smooth' });

Và với ví dụ dự phòng:

    try 
    { 
     window.scrollTo({ left: 0, top: 0, behavior: 'smooth' });
     } catch (e) {
      window.scrollTo(0, 0);
      }
40 hữu ích 2 bình luận chia sẻ
17

Được rồi, sau khi vò đầu bứt tai một chút, đây là một giải pháp có vẻ như đang hoạt động tốt.

Giống như trước đây, tôi đã khai báo id điều kiện của mình và một nút có lệnh gọi hàm scrollTo khi được nhấp vào.

Bây giờ, chỉ có hai tệp trong giải pháp là một dịch vụ sẽ giúp trả về cửa sổ tài liệu và thành phần của mẫu. Không có gì thay đổi trong dịch vụ cửa sổ từ trạng thái ở trên nhưng tôi sẽ bao gồm lại nó vì lợi ích của một câu trả lời tốt.

window.service.ts: kêu gọi https://gist.github.com/lokanx/cc022ee0b8999cd3b7f5 để được trợ giúp với phần này

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

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)

Tôi tạo ra một liệng để hiển thị ví dụ này làm việc: Plunk Ví dụ

17 hữu ích 0 bình luận chia sẻ
13

Cách dễ dàng hơn để đạt được điều này là sử dụng polyfill này: http://iamdustan.com/smoothscroll/

  1. Cài đặt nó dưới dạng: npm install Smoothscroll-polyfill
  2. Nhập nó vào tệp polyfill.ts của bạn dưới dạng: request ('Smoothscroll-polyfill'). Polyfill ();
  3. Bây giờ bạn có thể sử dụng tùy chọn hành vi của scrollIntoView dưới dạng:

    (document.querySelector ('#' + anchor)). scrollIntoView ({hành vi: 'mịn'});

13 hữu ích 5 bình luận chia sẻ
4

thí dụ:

function goToElement(elemId){
 let element = window.getElementById(elemId);
 element.scrollIntoView({behavior: "smooth"});
}
4 hữu ích 1 bình luận chia sẻ
2

Nếu bạn muốn một bước nhảy neo rất đơn giản hoạt động sau khi định tuyến và trong các dạng xem được định tuyến, bạn cũng có thể sử dụng ng2-simple-page-scroll .

<a simplePageScroll href="#myanchor">Go there</a>

Hoặc ngay sau khi định tuyến:

<a simplePageScroll [routerLink]="['Home']" href="#myanchor">Go there</a>

Nó thực hiện một bước nhảy tức thì đơn giản, nhưng nó hoạt động.

2 hữu ích 5 bình luận chia sẻ
2

Đối với bất kỳ ai vẫn đang tìm kiếm một cuộn mượt mà câu trả lời của @ alex-j rất phù hợp với tôi trong Angular 2.0 - nhưng tôi đã phải thay đổi dịch vụ Window thành này: -

import { Injectable } from '@angular/core';

function _window() : any {
    // return the global native browser window object
    return window;
}

@Injectable()
export class WindowRef {
    get nativeWindow() : any {
        return _window();
    }
}

Tất cả các đạo cụ cho blog này http://juristr.com/blog/2016/09/ng2-get-window-ref/ - bây giờ tôi có một dịch vụ cuộn mượt mà tôi có thể gọi từ mọi nơi :)

2 hữu ích 1 bình luận chia sẻ
1

tôi sử dụng mã này.

        var dis = distance  ;
        var interval = setInterval(() => {
            this.document.body.scrollTop = dis;
             dis=dis-5 ;
             if (dis<10){
                 clearInterval(interval);
             }
        }, 5);
1 hữu ích 0 bình luận chia sẻ
0

Nhờ câu trả lời được chấp nhận, tôi đã có thể triển khai "cuộn lên đầu trang" mượt mà. Cuộn lên đầu thực sự thậm chí còn dễ dàng hơn cuộn đến một phần tử mục tiêu cụ thể vì chúng tôi luôn cuộn đến vị trí 0. Đây là mã:

scrollTo(yPoint: number, duration: number) {
    setTimeout(() => {
        window.scrollTo(0, yPoint)
    }, duration);
    return;
}

smoothScrollToTop() {
    let startY = this.currentYPosition();
    let stopY = 0; // window top
    let distance = stopY > startY ? stopY - startY : startY - stopY;
    if (distance < 100) {
        window.scrollTo(0, stopY);
        return;
    }
    let speed = Math.round(distance / 100);
    let step = speed;
    speed = Math.max(9, speed); //min 9 otherwise it won't look smooth
    let leapY = stopY > startY ? startY + step : startY - step;
    let timer = 0;
    if (stopY > startY) {
        for (let i = startY; i < stopY; i += step) {
            // since setTimeout is asynchronous, the for-loop will will fire all scrolls
            // nearly simoultaniously. Therefore, we need to multiply the speed with
            // a counter which lets the scrolls start with a growing offset which lets the
            // setTimeout wait for a growing time till it scrolls there
            // that way, we prevent the window to scroll instantly to the target Yposition
            this.scrollTo(leapY, timer * speed);
            leapY += step; if (leapY > stopY) leapY = stopY; timer++;
        }
        return;
    } else {
        for (let i = startY; i > stopY; i -= step) {
            this.scrollTo(leapY, timer * speed);
            leapY -= step; if (leapY < stopY) leapY = stopY; timer++;
        }
    }
}

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;
}

Nếu muốn, bạn có thể để nút "Cuộn lên đầu" của mình xuất hiện động khi người dùng cuộn:

@HostListener('window:scroll', ['$event'])
onWindowScroll(event) {
    this.onScrollFadeInOutScrollToTopButton();
}

shouldShowScrollToTop: boolean = false;

onScrollFadeInOutScrollToTopButton() {
    this.shouldShowScrollToTop = (window.pageYOffset >= window.screen.height/2);
}

Và HTML cho Nút cuộn lên đầu:

<div class="back-to-top">
<button *ngIf="shouldShowScrollToTop" [@fadeInOutTrigger]="animateButtonEntryState" class="mat-primary" md-fab (click)="smoothScrollToTop()">^</button>

Như bạn có thể thấy, nút đó cũng có một trình kích hoạt hoạt ảnh. Bạn có thể nghĩ đến việc sử dụng một biểu tượng cho nút và lý tưởng nhất là nút của bạn phải có một position:fixed;phong cách riêng.

0 hữu ích 0 bình luận chia sẻ
-3

Có một cách tiếp cận khác, có thể được xem xét: sử dụng jQuery.

Có thể nó không quá thanh lịch như các giải pháp gốc, nhưng rất dễ dàng và hoạt động hoàn hảo.

Trong index.html của bạn, bạn phải thêm cái này vào cuối phần nội dung:

<script
src="https://code.jquery.com/jquery-3.1.1.min.js"
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
crossorigin="anonymous"></script>

<script>
  $(document).on("click", "a[href*='#']:not([href='#'])", function() {
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
      if (target.length) {
          $('html, body').animate({
          scrollTop: target.offset().top - 100
          }, 1000);
          return false;
      }
    }
  });

</script>

Và bây giờ bạn có thể sử dụng <a href("#section")>điều hướng đơn giản như sau:

<a href="#section2">Link</a>

Nó cũng hoạt động với định tuyến:

<a class="btn" role="button" routerLink="/contact" fragment="contact_form">Contact us!</a>
-3 hữu ích 1 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ scroll typescript angular smooth-scrolling , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading