कोणीय 5 हर रूट क्लिक पर शीर्ष पर स्क्रॉल करें


103

मैं कोणीय 5 का उपयोग कर रहा हूं। मेरे पास एक डैशबोर्ड है जहां मेरे पास छोटी सामग्री के साथ कुछ खंड हैं और कुछ अनुभागों में इतनी बड़ी सामग्री है कि मुझे शीर्ष पर जाते समय राउटर बदलते समय एक समस्या का सामना करना पड़ रहा है। हर बार मुझे शीर्ष पर जाने के लिए स्क्रॉल करने की आवश्यकता होती है। क्या कोई मुझे इस मुद्दे को हल करने में मदद कर सकता है ताकि जब मैं राउटर बदलूं तो मेरा विचार हमेशा शीर्ष पर रहे।

अग्रिम में धन्यवाद।


जवाबों:


218

कुछ उपाय हैं, उन सभी की जांच सुनिश्चित करें :)


राउटर आउटलेट activateकिसी भी समय किसी नए घटक को इंस्टेंट किए जाने पर घटना का उत्सर्जन करेगा , इसलिए हम (activate)शीर्ष पर स्क्रॉल करने के लिए उपयोग कर सकते हैं (उदाहरण के लिए)

app.component.html

<router-outlet (activate)="onActivate($event)" ></router-outlet>

app.component.ts

onActivate(event) {
    window.scroll(0,0);
    //or document.body.scrollTop = 0;
    //or document.querySelector('body').scrollTo(0,0)
    ...
}

छूट के लिए उपयोग करें, एक चिकनी स्क्रॉल के लिए यह समाधान :

    onActivate(event) {
        let scrollToTop = window.setInterval(() => {
            let pos = window.pageYOffset;
            if (pos > 0) {
                window.scrollTo(0, pos - 20); // how far to scroll on each step
            } else {
                window.clearInterval(scrollToTop);
            }
        }, 16);
    }

यदि आप चयनात्मक होना चाहते हैं, तो कहें कि प्रत्येक घटक को स्क्रॉलिंग को ट्रिगर नहीं करना चाहिए, आप इसे ifइस तरह से एक बयान में देख सकते हैं :

onActivate(e) {
    if (e.constructor.name)==="login"{ // for example
            window.scroll(0,0);
    }
}

Angular6.1 के बाद से, हम { scrollPositionRestoration: 'enabled' }उत्सुकता से लोड किए गए मॉड्यूल पर भी उपयोग कर सकते हैं और इसे सभी मार्गों पर लागू किया जाएगा:

RouterModule.forRoot(appRoutes, { scrollPositionRestoration: 'enabled' })

यह पहले से ही चिकनी स्क्रॉलिंग भी करेगा। हालांकि यह हर मार्ग पर करने के लिए असुविधाजनक है।


एक अन्य उपाय राउटर एनीमेशन पर शीर्ष स्क्रॉल करना है। इसे हर उस संक्रमण में जोड़ें जहां आप शीर्ष पर स्क्रॉल करना चाहते हैं:

query(':enter, :leave', style({ position: 'fixed' }), { optional: true }) 

4
यह काम कर रहा है । आपके उत्तर के लिए धन्यवाद। आप मेरे लिए बहुत समय बचाते हैं
raihan

2
windowऑब्जेक्ट पर स्क्रॉल इवेंट कोणीय 5 में काम नहीं कर रहे हैं। कोई भी अनुमान लगाता है कि क्यों?
साहिल बब्बर

2
एक असली नायक यहाँ। हताशा के संभावित घंटों को बचाया। धन्यवाद!
अंजना सिल्वा

1
@AnjanaSilva, सकारात्मक टिप्पणी के लिए धन्यवाद! मुझे बहुत खुशी है कि यह आपकी मदद कर सकता है :)
वेगा

2
क्या आलसी लोडेड मॉड्यूल के लिए कोई रास्ता है?
पंकज प्रकाश

54

यदि आप कोणीय 6 में इस समस्या का सामना करते हैं, तो आप इसे scrollPositionRestoration: 'enabled'app-routing.module.ts के RouterModule में पैरामीटर जोड़कर ठीक कर सकते हैं :

@NgModule({
  imports: [RouterModule.forRoot(routes,{
    scrollPositionRestoration: 'enabled'
  })],
  exports: [RouterModule]
})

7
कृपया कोड की तस्वीरें पोस्ट न करें। कोड को केवल अपने उत्तर में ही कॉपी-पेस्ट करें।
20

2
ज़रूर। अगली बार करूंगा। मैं यहाँ सिर्फ थोड़े नया हूँ। :)
नीमजेज़

4
ध्यान दें कि 6-Nov-2019 को Angular 8 का उपयोग करते हुए, कम से कम, scrollPositionRestorationसंपत्ति गतिशील पृष्ठ सामग्री (यानी, जहां पृष्ठ सामग्री अतुल्यकालिक रूप से भरी हुई है) के साथ काम नहीं करती है: इस कोणीय बग रिपोर्ट देखें: github.com/angular- आयताकार / अंक / 24547
dbeachy1

25

EDIT: कोणीय ६+ के लिए, निमेश निषाद इन्दिमेदारा के उत्तर का उल्लेख करें:

RouterModule.forRoot(routes, {
    scrollPositionRestoration: 'enabled'
});

मूल उत्तर:

यदि सभी विफल हो जाते हैं, तो शीर्ष पर कुछ खाली HTML तत्व (जैसे: div) बनाएँ (या इच्छित स्क्रॉल करें) id = "top" टेम्पलेट पर (या मूल टेम्पलेट):

<div id="top"></div>

और घटक में:

  ngAfterViewInit() {
    // Hack: Scrolls to top of Page after page view initialized
    let top = document.getElementById('top');
    if (top !== null) {
      top.scrollIntoView();
      top = null;
    }
  }

2
इस समाधान ने मेरे लिए काम किया (क्रोम और एज पर परीक्षण किया गया)। स्वीकृत समाधान मेरे प्रोजेक्ट (Angular5)
Rob van Meeuwen

@RobvanMeeuwen, अगर मेरा जवाब काम नहीं करता तो शायद आप इसे उसी तरह से लागू नहीं करते। यह समाधान सीधे डोम से छेड़छाड़ कर रहा है जो या तो सुरक्षित नहीं है
वेगा

@Vega, इसलिए मैंने इसे हैक कहा है। आपका समाधान उचित है। यहाँ कुछ लोग आपका कार्यान्वयन करने में सक्षम नहीं थे इसलिए मैंने फॉलबैक हैक की पेशकश की। उन्हें इस बिंदु पर अपने संस्करण के आधार पर अपने कोड को रिफलेक्टर करना चाहिए।
जियोवर

इस सब से समाधान मेरे लिए काम है। धन्यवाद @GeoRover
गंगानी रोशन

कोणीय 6+ के लिए, निमेष निषाद इन्दीमेदरा के उत्तर का उपयोग करें।
जियोवर


6

हालाँकि @Vega आपके प्रश्न का सीधा उत्तर प्रदान करता है, फिर भी मुद्दे हैं। यह ब्राउजर के बैक / फॉरवर्ड बटन को तोड़ देता है। यदि आप उपयोगकर्ता ब्राउज़र को वापस या फ़ॉरवर्ड बटन पर क्लिक करते हैं, तो वे अपना स्थान खो देते हैं और शीर्ष पर स्क्रॉल का रास्ता प्राप्त कर लेते हैं। यह आपके उपयोगकर्ताओं के लिए थोड़ा सा दर्द हो सकता है अगर उन्हें लिंक करने के लिए नीचे स्क्रॉल करना पड़ता है और केवल स्क्रॉलबार खोजने के लिए वापस क्लिक करने का निर्णय लिया है जो शीर्ष पर रीसेट हो गया था।

यहाँ समस्या का मेरा समाधान है।

export class AppComponent implements OnInit {
  isPopState = false;

  constructor(private router: Router, private locStrat: LocationStrategy) { }

  ngOnInit(): void {
    this.locStrat.onPopState(() => {
      this.isPopState = true;
    });

    this.router.events.subscribe(event => {
      // Scroll to top if accessing a page, not via browser history stack
      if (event instanceof NavigationEnd && !this.isPopState) {
        window.scrollTo(0, 0);
        this.isPopState = false;
      }

      // Ensures that isPopState is reset
      if (event instanceof NavigationEnd) {
        this.isPopState = false;
      }
    });
  }
}

2
उन्नत कोड और अच्छे समाधान के लिए धन्यवाद। लेकिन कभी-कभी @Vega समाधान बेहतर होता है, क्योंकि यह एनीमेशन और गतिशील पृष्ठ ऊंचाई के साथ कई समस्याओं को हल करता है। यदि आपके पास सामग्री और सरल मार्ग एनीमेशन के साथ लंबा पृष्ठ है, तो आप समाधान अच्छा है। मैं इसे कई एनीमेशन और डायनामिक्स ब्लॉक के साथ पृष्ठ पर आज़माता हूं और यह इतना अच्छा नहीं है। मुझे लगता है कि कभी-कभी हम अपने ऐप के लिए 'बैक पोजीशन' का त्याग कर सकते हैं। लेकिन अगर नहीं - तो आप सबसे अच्छा है जो मुझे कोणीय के लिए दिखाई देता है। फिर से धन्यवाद
डेनिस सवेन्को

5

मेरे मामले में मैंने अभी जोड़ा है

window.scroll(0,0);

में ngOnInit()और उसके काम कर ठीक।


4

कोणीय संस्करण 6+ से window.scroll (0,0) का उपयोग करने की आवश्यकता नहीं है

राउटर को कॉन्फ़िगर करने के लिए 6+@ रिप्रेंटेंट्स विकल्पों से कोणीय संस्करण ।docs

interface ExtraOptions {
  enableTracing?: boolean
  useHash?: boolean
  initialNavigation?: InitialNavigation
  errorHandler?: ErrorHandler
  preloadingStrategy?: any
  onSameUrlNavigation?: 'reload' | 'ignore'
  scrollPositionRestoration?: 'disabled' | 'enabled' | 'top'
  anchorScrolling?: 'disabled' | 'enabled'
  scrollOffset?: [number, number] | (() => [number, number])
  paramsInheritanceStrategy?: 'emptyOnly' | 'always'
  malformedUriErrorHandler?: (error: URIError, urlSerializer: UrlSerializer, url: string) => UrlTree
  urlUpdateStrategy?: 'deferred' | 'eager'
  relativeLinkResolution?: 'legacy' | 'corrected'
}

scrollPositionRestoration?: 'disabled' | 'enabled' | 'top'में उपयोग कर सकते हैं

उदाहरण:

RouterModule.forRoot(routes, {
    scrollPositionRestoration: 'enabled'|'top' 
});

और अगर किसी को स्क्रॉलिंग को मैन्युअल रूप से नियंत्रित करने की आवश्यकता होती है, तो window.scroll(0,0) कोणीय V6 के सामान्य पैकेज के बजाय उपयोग करने की आवश्यकता नहीं है ViewPortScoller

abstract class ViewportScroller {
  static ngInjectableDef: defineInjectable({ providedIn: 'root', factory: () => new BrowserViewportScroller(inject(DOCUMENT), window) })
  abstract setOffset(offset: [number, number] | (() => [number, number])): void
  abstract getScrollPosition(): [number, number]
  abstract scrollToPosition(position: [number, number]): void
  abstract scrollToAnchor(anchor: string): void
  abstract setHistoryScrollRestoration(scrollRestoration: 'auto' | 'manual'): void
}

उपयोग बहुत सीधा उदाहरण है:

import { Router } from '@angular/router';
import {  ViewportScroller } from '@angular/common'; //import
export class RouteService {

  private applicationInitialRoutes: Routes;
  constructor(
    private router: Router;
    private viewPortScroller: ViewportScroller//inject
  )
  {
   this.router.events.pipe(
            filter(event => event instanceof NavigationEnd))
            .subscribe(() => this.viewPortScroller.scrollToPosition([0, 0]));
}

4

यदि आपके मैट-सिडेनव का उपयोग राउटर आउटलेट को एक आईडी देता है (यदि आपके पास माता-पिता और बच्चे के राउटर आउटलेट हैं) और इसमें सक्रिय फ़ंक्शन का <router-outlet id="main-content" (activate)="onActivate($event)"> उपयोग करें और शीर्ष स्क्रॉल करने के लिए इस 'मैट-सिडेनव-कंटेंट' क्वेरी चयनकर्ता का उपयोग करें। onActivate(event) { document.querySelector("mat-sidenav-content").scrollTo(0, 0); }


एक का उपयोग किए बिना भी महान काम करता है id ( router-outletमेरे ऐप पर एक सिंगल है )। मैंने इसे अधिक 'कोणीय तरीके' पर भी किया: @ViewChild(MatSidenavContainer) sidenavContainer: MatSidenavContainer; onActivate() { this.sidenavContainer.scrollable.scrollTo({ left: 0, top: 0 }); }
GCSDC

3

मैं इस समस्या के समाधान के लिए एक निर्मित की तलाश में रहता हूं जैसे कि एंगुलरजेएस में है। लेकिन तब तक यह समाधान मेरे लिए काम करता है, यह सरल है, और बैक बटन कार्यक्षमता को संरक्षित करता है।

app.component.html

<router-outlet (deactivate)="onDeactivate()"></router-outlet>

app.component.ts

onDeactivate() {
  document.body.scrollTop = 0;
  // Alternatively, you can scroll to top by using this other call:
  // window.scrollTo(0, 0)
}

मूल पोस्ट से zurfyx का उत्तर


3

आपको बस एक फ़ंक्शन बनाने की आवश्यकता है जिसमें आपकी स्क्रीन की स्क्रॉलिंग का समायोजन हो

उदाहरण के लिए

window.scroll(0,0) OR window.scrollTo() by passing appropriate parameter.

window.scrollTo (xpos, ypos) -> अपेक्षित पैरामीटर।


2

यहाँ एक समाधान है जो केवल घटक के ऊपर स्क्रॉल करता है यदि पहली बार EACH घटक के लिए दौरा कर रहा है (मामले में आपको कुछ अलग घटक करने की आवश्यकता है):

प्रत्येक घटक में:

export class MyComponent implements OnInit {

firstLoad: boolean = true;

...

ngOnInit() {

  if(this.firstLoad) {
    window.scroll(0,0);
    this.firstLoad = false;
  }
  ...
}


2

कोणीय 6.1 और बाद में:

आप इसे प्राप्त करने के लिए विकल्प के साथ कोणीय 6.1+ में उपलब्ध समाधान में उपयोग कर सकते हैं ।scrollPositionRestoration: 'enabled'

@NgModule({
  imports: [RouterModule.forRoot(routes,{
    scrollPositionRestoration: 'enabled'
  })],
  exports: [RouterModule]
})

कोणीय 6.0 और पहले:

import { Component, OnInit } from '@angular/core';
import { Router, NavigationStart, NavigationEnd } from '@angular/router';
import { Location, PopStateEvent } from "@angular/common";

@Component({
    selector: 'my-app',
    template: '<ng-content></ng-content>',
})
export class MyAppComponent implements OnInit {

    private lastPoppedUrl: string;
    private yScrollStack: number[] = [];

    constructor(private router: Router, private location: Location) { }

    ngOnInit() {
        this.location.subscribe((ev:PopStateEvent) => {
            this.lastPoppedUrl = ev.url;
        });
        this.router.events.subscribe((ev:any) => {
            if (ev instanceof NavigationStart) {
                if (ev.url != this.lastPoppedUrl)
                    this.yScrollStack.push(window.scrollY);
            } else if (ev instanceof NavigationEnd) {
                if (ev.url == this.lastPoppedUrl) {
                    this.lastPoppedUrl = undefined;
                    window.scrollTo(0, this.yScrollStack.pop());
                } else
                    window.scrollTo(0, 0);
            }
        });
    }
}

नोट: अपेक्षित व्यवहार यह है कि जब आप पृष्ठ पर वापस जाते हैं, तो इसे उसी स्थान तक नीचे स्क्रॉल किया जाना चाहिए जब आप लिंक पर क्लिक करते थे, लेकिन हर पृष्ठ पर पहुंचने पर शीर्ष पर स्क्रॉल करना।



2

स्क्रॉल फंक्शन की तलाश कर रहे कुछ लोगों के लिए बस फ़ंक्शन जोड़ें और जब कभी ज़रूरत हो तो कॉल करें

scrollbarTop(){

  window.scroll(0,0);
}

1

इसे इस्तेमाल करे:

app.component.ts

import {Component, OnInit, OnDestroy} from '@angular/core';
import {Router, NavigationEnd} from '@angular/router';
import {filter} from 'rxjs/operators';
import {Subscription} from 'rxjs';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit, OnDestroy {
    subscription: Subscription;

    constructor(private router: Router) {
    }

    ngOnInit() {
        this.subscription = this.router.events.pipe(
            filter(event => event instanceof NavigationEnd)
        ).subscribe(() => window.scrollTo(0, 0));
    }

    ngOnDestroy() {
        this.subscription.unsubscribe();
    }
}

1

घटक: टेम्प्लेट में एक एक्शन बनाने के बजाय सभी रूटिंग ईवेंट की सदस्यता लें और नेवीगेशन पर स्क्रॉल करें / b / c अन्यथा आप इसे खराब नेवी या ब्लॉक किए गए मार्गों आदि पर आग लगा देंगे ... यह जानने का एक निश्चित तरीका है कि यदि एक रूट को सफलतापूर्वक नेविगेट किया जाता है, फिर स्क्रॉल स्क्रॉल करें। नहीं तो कुछ न करें।

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit, OnDestroy {

  router$: Subscription;

  constructor(private router: Router) {}

  ngOnInit() {
    this.router$ = this.router.events.subscribe(next => this.onRouteUpdated(next));
  }

  ngOnDestroy() {
    if (this.router$ != null) {
      this.router$.unsubscribe();
    }
  }

  private onRouteUpdated(event: any): void {
    if (event instanceof NavigationEnd) {
      this.smoothScrollTop();
    }
  }

  private smoothScrollTop(): void {
    const scrollToTop = window.setInterval(() => {
      const pos: number = window.pageYOffset;
      if (pos > 0) {
          window.scrollTo(0, pos - 20); // how far to scroll on each step
      } else {
          window.clearInterval(scrollToTop);
      }
    }, 16);
  }

}

एचटीएमएल

<router-outlet></router-outlet>

1

इसे इस्तेमाल करे

@NgModule({
  imports: [RouterModule.forRoot(routes,{
    scrollPositionRestoration: 'top'
  })],
  exports: [RouterModule]
})

यह कोड कोणीय 6 <= समर्थित है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.