কৌণিক 2 রুট পরিবর্তনতে শীর্ষে স্ক্রোল করুন


295

আমার কৌনিক 2 অ্যাপে যখন আমি কোনও পৃষ্ঠা নীচে স্ক্রোল করি এবং পৃষ্ঠার নীচে লিঙ্কটি ক্লিক করি তখন এটি রুট পরিবর্তন করে এবং আমাকে পরবর্তী পৃষ্ঠায় নিয়ে যায় তবে এটি পৃষ্ঠার শীর্ষে স্ক্রোল করে না। ফলস্বরূপ, যদি প্রথম পৃষ্ঠাটি দীর্ঘ হয় এবং ২ য় পৃষ্ঠায় কয়েকটি বিষয়বস্তু থাকে তবে এটি এমন একটি ধারণা দেয় যে ২ য় পৃষ্ঠায় বিষয়বস্তুর অভাব রয়েছে। যেহেতু বিষয়বস্তুগুলি কেবলমাত্র পৃষ্ঠার শীর্ষে স্ক্রোল করা থাকলে তা দৃশ্যমান।

আমি উপাদানটির এনজিআইনেটে পৃষ্ঠার শীর্ষে উইন্ডোটি স্ক্রোল করতে পারি তবে, এর চেয়ে ভাল কোনও সমাধান আছে যা আমার অ্যাপ্লিকেশনটিতে সমস্ত রুট স্বয়ংক্রিয়ভাবে পরিচালনা করতে পারে?


20
অ্যাঙ্গুলার 6.1 যেহেতু আমরা আগ্রহীভাবে লোড হওয়া মডিউলগুলিতে বা কেবল অ্যাপ্লিকেশন.মডিউলগুলিতে {স্ক্রোলপোজেনস্টোরস্টোরেশন: 'সক্ষম' use ব্যবহার করতে পারি এবং এটি সমস্ত রুটে প্রয়োগ করা হবে। RouterModule.forRoot(appRoutes, { scrollPositionRestoration: 'enabled' })
মানওয়াল

মিমি ওব্রিগডো স্যুইচিং ফানসিওনো পারফরম্যান্স পারফর্মেন্স মাইন্ড :)
রাফেল গডোই

এক ব্যক্তি ফোকাস উল্লিখিত না? অ্যাক্সেসিবিলিটি / স্ক্রিনের পাঠকদের যথাযথভাবে সমর্থন করা আগের চেয়ে আরও গুরুত্বপূর্ণ এবং আপনি যদি মনোযোগ বিবেচনা না করে কেবল শীর্ষে স্ক্রোল করেন তবে পরবর্তী ট্যাব কীপ্রেসটি স্ক্রিনের নীচে যেতে পারে।
সাইমন_উইভার

উত্তর:


384

আপনি আপনার মূল উপাদানটিতে একটি রুট পরিবর্তন শ্রোতার নিবন্ধন করতে পারেন এবং রুট পরিবর্তনের শীর্ষে স্ক্রোল করতে পারেন।

import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';

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

    ngOnInit() {
        this.router.events.subscribe((evt) => {
            if (!(evt instanceof NavigationEnd)) {
                return;
            }
            window.scrollTo(0, 0)
        });
    }
}

11
window.scrollTo(0, 0)তুলনায় আরও সংক্ষিপ্ত document.body.scrollTop = 0;এবং আরও পঠনযোগ্য আইএমও।
মার্ক ই। হাজেস

10
কেউ কি খেয়াল করেছেন, এটি বাস্তবায়নের পরেও, আইফোনটির সাফারি ব্রাউজারে বিষয়টি স্থির থাকে। কোন চিন্তা?
rgk

1
@ মেহাজে মনে হচ্ছে আপনার উত্তরটি সবচেয়ে ভাল। উইন্ডো.বিডি.স্ক্রোলটপ ফায়ারফক্স ডেস্কটপে আমার জন্য কাজ করে না। তাই আপনাকে ধন্যবাদ !
কারনাইল

3
এটি আমার পক্ষে কাজ করেছিল তবে এটি ডিফল্ট "পিছনে" বোতামের আচরণটি ভেঙে দেয়। ফিরে যেতে আগের স্ক্রোল অবস্থানটি মনে রাখা উচিত।
জ্যাককালিশ

6
এই কাজ !! যদিও আমি মসৃণ স্ক্রোলিং শীর্ষে $("body").animate({ scrollTop: 0 }, 1000);window.scrollTo(0, 0)
সঞ্চার

360

কৌণিক 6.1 এবং পরবর্তী :

কৌণিক 6.1 (2018-07-25 এ প্রকাশিত) "রাউটার স্ক্রোল অবস্থান পুনরুদ্ধার" নামে একটি বৈশিষ্ট্যের মাধ্যমে এই ইস্যুটি পরিচালনা করতে অন্তর্নির্মিত সমর্থন যুক্ত করেছে। অফিসিয়াল কৌণিক ব্লগে বর্ণিত হিসাবে , আপনাকে কেবল রাউটার কনফিগারেশনে এটি সক্ষম করতে হবে:

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

তদ্ব্যতীত, ব্লগটি বলেছে "এটি প্রত্যাশিত যে এটি ভবিষ্যতে বড় প্রকাশে ডিফল্ট হয়ে উঠবে"। এখনও অবধি এটি ঘটেনি (কৌণিক ৮.২ অনুসারে), তবে শেষ পর্যন্ত আপনার কোডে কিছু করার দরকার নেই, এবং এটি বাক্সের বাইরে সঠিকভাবে কাজ করবে।

আপনি এই বৈশিষ্ট্য এবং অফিসিয়াল ডক্সে এই আচরণটি কীভাবে কাস্টমাইজ করবেন সে সম্পর্কে আরও বিশদ দেখতে পাবেন can

কৌণিক 6.0 এবং তার আগের :

@ গিলহেরেমিরিলেসসের দুর্দান্ত উত্তরটি মূল সমস্যাটি সংশোধন করার সময়, আপনি যখন পিছনে বা এগিয়ে যান (ব্রাউজার বোতামগুলির সাথে বা কোডে অবস্থানের মাধ্যমে) নেভিগেট করেন তখন আপনি যে স্বাভাবিক আচরণটি প্রত্যাশা করেন তা ভেঙে এটি একটি নতুন প্রবর্তন করে। প্রত্যাশিত আচরণটি হ'ল আপনি যখন পৃষ্ঠায় ফিরে যান, আপনি লিঙ্কটি ক্লিক করার সময় এটি একই জায়গায় স্ক্রোল হওয়া উচিত, তবে প্রতিটি পৃষ্ঠায় পৌঁছানোর সময় শীর্ষে স্ক্রোল করা স্পষ্টতই এই প্রত্যাশাটি ভঙ্গ করে।

নীচের কোডটি লোকেশনের পপস্টেটএভেন্ট ক্রমটি সাবস্ক্রাইব করে এবং নতুন আগত পৃষ্ঠায় যদি এমন কোনও ঘটনার ফলাফল হয় তবে স্ক্রোল থেকে টপ-শীর্ষ যুক্তিকে এড়িয়ে এই জাতীয় নেভিগেশন সনাক্ত করার জন্য যুক্তিটি প্রসারিত করে।

আপনি যে পৃষ্ঠাগুলি থেকে নেভিগেট করেছেন সেটি পুরো ভিউপোর্টটি কভার করার জন্য যদি দীর্ঘ হয় তবে স্ক্রোলের অবস্থানটি স্বয়ংক্রিয়ভাবে পুনরুদ্ধার করা হয়, তবে @ জর্দান নেলসন সঠিকভাবে উল্লেখ করেছেন, পৃষ্ঠাটি যদি ছোট হয় তবে আপনাকে মূল y স্ক্রোলের অবস্থানটি ট্র্যাক রাখতে হবে এবং পুনরুদ্ধার করতে হবে আপনি পৃষ্ঠায় ফিরে গেলে স্পষ্টতই। কোডের আপডেট হওয়া সংস্করণটিও সর্বদা স্পষ্টভাবে স্ক্রোলের অবস্থান পুনরুদ্ধার করে এই কেসটিকে কভার করে।

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
এটি অ্যাপ্লিকেশন উপাদানটিতে সরাসরি হওয়া উচিত, অথবা এটিতে ব্যবহৃত একক উপাদানে (এবং তাই পুরো অ্যাপ্লিকেশন দ্বারা ভাগ করা) should উদাহরণস্বরূপ, আমি এটিকে শীর্ষস্থানীয় নেভিগেশন বারের উপাদানটিতে অন্তর্ভুক্ত করেছি। আপনার সমস্ত উপাদানগুলিতে আপনাকে অন্তর্ভুক্ত করা উচিত নয়।
ফার্নান্দো ইশেভারিয়া

3
আপনি এটি করতে পারেন এবং এটি কোডটি অন্যান্য, ব্রাউজারহীন, প্ল্যাটফর্মগুলির সাথে আরও ব্যাপকভাবে সামঞ্জস্য করবে। বাস্তবায়ন বিশদের জন্য stackoverflow.com/q/34177221/2858481 দেখুন ।
ফার্নান্দো ইশেভারিয়া

3
আপনি যদি আধুনিক ব্রাউজারগুলিতে পিছনে / ফরোয়ার্ড বোতামটি ক্লিক করেন এবং ধরে রাখেন তবে একটি মেনু প্রদর্শিত হবে যা আপনাকে আপনার পূর্ববর্তী / পরবর্তীগুলির সাথে সাথে অন্য স্থানে নেভিগেট করতে দেয়। আপনি যদি এটি করেন তবে এই সমাধানটি ভেঙে যায়। এটি বেশিরভাগ ক্ষেত্রে প্রান্তের ক্ষেত্রে তবে উল্লেখযোগ্য।
অ্যাডামডপোর্ট


1
নেস্টেড উপাদানগুলির জন্য "রাউটার স্ক্রোল অবস্থান পুনরুদ্ধার" সক্ষম করার কোনও উপায় আছে বা এটি কেবল তার জন্য কাজ করে body?
ভোল্ট

61

কৌণিক 6.1 থেকে, আপনি এখন ঝামেলা এড়াতে এবং দ্বিতীয় প্যারামিটার হিসাবে extraOptionsআপনার কাছে RouterModule.forRoot()যেতে পারেন এবং scrollPositionRestoration: enabledযখনই রুট পরিবর্তন হয় তখন শীর্ষে স্ক্রোল করতে অ্যাঙ্গুলারকে বলতে পারেন ।

ডিফল্ট হিসাবে আপনি এটি পাবেন app-routing.module.ts:

const routes: Routes = [
  {
    path: '...'
    component: ...
  },
  ...
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      scrollPositionRestoration: 'enabled', // Add options right here
    })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }

কৌণিক অফিসিয়াল ডক্স


3
যদিও উপরের উত্তরটি আরও বর্ণনামূলক হলেও আমি পছন্দ করি যে এই উত্তরটি আমাকে ঠিক কোথায় যেতে হবে তা
বলেছিল

32

আপনি পর্যবেক্ষণযোগ্য filterপদ্ধতির সুবিধা গ্রহণ করে এটিকে আরও সংক্ষেপে লিখতে পারেন :

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

কৌণিক উপাদান 2 সিডেনাভ ব্যবহার করার সময় আপনার যদি শীর্ষে স্ক্রোলিংয়ের সমস্যা হয় তবে এটি সাহায্য করবে। উইন্ডো বা ডকুমেন্টের বডিটিতে স্ক্রোলবার থাকবে না সুতরাং আপনাকে sidenavসামগ্রীতে ধারক পেতে এবং সেই উপাদানটি স্ক্রোল করতে হবে, অন্যথায় ডিফল্ট হিসাবে উইন্ডোটিকে স্ক্রোল করার চেষ্টা করুন।

this.router.events.filter(event => event instanceof NavigationEnd)
  .subscribe(() => {
      const contentContainer = document.querySelector('.mat-sidenav-content') || this.window;
      contentContainer.scrollTo(0, 0);
});

এছাড়াও, কৌণিক সিডিকে ভি 6.x এর এখন একটি স্ক্রোলিং প্যাকেজ রয়েছে যা স্ক্রোলিং পরিচালনা করতে সহায়তা করতে পারে।


2
গ্রেট! আমার জন্য যে কাজ করেছে -document.querySelector('.mat-sidenav-content .content-div').scrollTop = 0;
আমির তুগি

এমটিপল্টজ এবং @ আমিরতুগীতে চমৎকার একটি ফেল্লা। এই মুহূর্তে এটি মোকাবেলা, এবং আপনি আমার জন্য এটি পেরেক, চিয়ার্স! সম্ভবত এমডি-টুলবারের অবস্থানটি থাকা অবস্থায় ম্যাটারিয়াল 2 গুলি ভাল না খেলে অবশ্যম্ভাবী আমার নিজের পাশের নাভি ঘূর্ণায়মান হবে: স্থির (উপরে)। যদি না আপনার লোকেরা ধারণা না থাকে .... ????
টিম হারকার

আমার উত্তরটি পেতে পারে ... স্ট্যাকওভারফ্লো
টিম হার্কার

16

আপনার যদি সার্ভার সাইড রেন্ডারিং থাকে তবে সার্ভারে কোডটি চালাবেন না এমন সতর্কতা অবলম্বন করা উচিত windows, যেখানে সেই চলকটি বিদ্যমান নেই। এর ফলে কোড ভঙ্গ হবে।

export class AppComponent implements OnInit {
  routerSubscription: Subscription;

  constructor(private router: Router,
              @Inject(PLATFORM_ID) private platformId: any) {}

  ngOnInit() {
    if (isPlatformBrowser(this.platformId)) {
      this.routerSubscription = this.router.events
        .filter(event => event instanceof NavigationEnd)
        .subscribe(event => {
          window.scrollTo(0, 0);
        });
    }
  }

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

isPlatformBrowserবর্তমান প্ল্যাটফর্মটি যেখানে অ্যাপ্লিকেশনটি প্রদর্শিত হয় তা ব্রাউজার কিনা তা যাচাই করতে ব্যবহৃত একটি ফাংশন। আমরা এটি ইনজেকশন দেইplatformId

ভেরিয়েবলের অস্তিত্ব পরীক্ষা windowsকরা, নিরাপদ থাকাও এইভাবে সম্ভব :

if (typeof window != 'undefined')

1
আপনি উদ্বুদ্ধ করতে প্রয়োজন হবে না PLATFORM_IDconstructorএবং ডি প্যারামিটার হিসাবে এই মান দিতে isPlatformBrowserপদ্ধতি?
পুল ক্রুইজ্ট

1
@ পিয়ারডুক হ্যাঁ, উত্তরটি ভুল। isPlatformBrowserএটি একটি ফাংশন এবং সর্বদা সত্যবাদী হবে। আমি এখন এটি সম্পাদনা করেছি।
লাজার লজুবেনভিভিć

ধন্যবাদ! এখনই ঠিক! : শুধু এপিআই যাচাই github.com/angular/angular/blob/...
Raptor

13

ক্লিক অ্যাকশন দিয়ে কেবল এটি সহজ করুন

আপনার মূল উপাদানটিতে এইচটিএমএল রেফারেন্স করুন # স্ক্রোলকন্টেইনার

<div class="main-container" #scrollContainer>
    <router-outlet (activate)="onActivate($event, scrollContainer)"></router-outlet>
</div>

প্রধান উপাদান .ts

onActivate(e, scrollContainer) {
    scrollContainer.scrollTop = 0;
}

স্ক্রোল করার উপাদানটি scrollContainerপ্রথম নোডে নাও থাকতে পারে, আপনাকে বস্তুটিতে কিছুটা খনন করতে হতে পারে, আমার জন্য এটি কী কাজ করেছেscrollContainer .scrollable._elementRef.nativeElement.scrollTop = 0
বায়রন লোপেজ

13

কৌণিক ইদানীং একটি নতুন বৈশিষ্ট্য প্রবর্তন করেছে, কৌণিক রাউটিং মডিউলটির ভিতরে নীচের মত পরিবর্তন করা হয়েছে

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

12

সেরা উত্তরটি কৌণিক গিটহাব আলোচনায় থাকে ( রুট পরিবর্তন করা নতুন পৃষ্ঠায় শীর্ষে যায় না )।

সম্ভবত আপনি কেবল রুট রাউটার পরিবর্তনে শীর্ষে যেতে চান (বাচ্চাদের মধ্যে নয়, কারণ আপনি কোনও ট্যাবসেটে অলস লোড দিয়ে রুটগুলি লোড করতে পারেন)

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

জনিজনমে সম্পূর্ণ ক্রেডিট ( মূল পোস্ট )




4

আপনার যদি কেবল শীর্ষে পৃষ্ঠায় স্ক্রোলের প্রয়োজন হয় তবে আপনি এটি করতে পারেন (সেরা সমাধান নয়, তবে দ্রুত)

document.getElementById('elementId').scrollTop = 0;

4

এখানে একটি সমাধান যা আমি নিয়ে এসেছি's আমি রাউটার ইভেন্টগুলির সাথে লোকেশনস্ট্রেজিটি তৈরি করেছি। কোনও ব্যবহারকারী বর্তমানে ব্রাউজারের ইতিহাসের মধ্য দিয়ে কখন যাচ্ছেন তা জানতে বুলিয়ান সেট করতে লোকেশনস্ট্রেজি ব্যবহার করে। এইভাবে, আমাকে একগুচ্ছ ইউআরএল এবং ওয়াই-স্ক্রোল ডেটা সংরক্ষণ করতে হবে না (যা কোনওভাবেই কার্যকর হয় না, যেহেতু প্রতিটি ডেটা URL এর ভিত্তিতে প্রতিস্থাপন করা হয়)। ব্যবহারকারী কোনও ব্রাউজারে পিছনে বা ফরোয়ার্ড বোতামটি ধরে রাখার সিদ্ধান্ত নেয় এবং কেবল একটির চেয়ে একাধিক পৃষ্ঠাগুলি পিছনে বা এগিয়ে যায় This

PS আমি কেবলমাত্র আইই, ক্রোম, ফায়ারফক্স, সাফারি এবং অপেরা (এই পোস্ট হিসাবে) এর সর্বশেষতম সংস্করণে পরীক্ষা করেছি।

আশাকরি এটা সাহায্য করবে.

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

4

এই দ্রবণটি @ ফার্নান্দোএচেরিয়ারিয়া এবং @ গিলহেরেমিরিলেসের সমাধানের উপর ভিত্তি করে তৈরি হয়েছে তবে এটি আরও সংক্ষিপ্ত এবং অ্যাঙ্গুলার রাউটার সরবরাহকারী পপস্টেট প্রক্রিয়াগুলির সাথে কাজ করে। এটি একাধিক পরপর নেভিগেশনের স্ক্রোল স্তর সংরক্ষণ এবং পুনরুদ্ধার করার অনুমতি দেয়।

আমরা একটি মানচিত্রে প্রতিটি নেভিগেশন রাষ্ট্রের জন্য স্ক্রোল অবস্থানগুলি সঞ্চয় করি scrollLevels। এক যে ছিলো popstate ইভেন্ট, রাষ্ট্র যে সম্পর্কে পুনঃস্থাপন করতে কৌণিক রাউটার দ্বারা সরবরাহ করা হয় এর আইডি হল: event.restoredState.navigationId। এটি তখন থেকে সেই রাজ্যের শেষ স্ক্রোল স্তরটি পেতে ব্যবহার করা হয় scrollLevels

যদি এই রুটের জন্য কোনও সঞ্চিত স্ক্রোল স্তর না থাকে তবে এটি আপনার প্রত্যাশা অনুযায়ী শীর্ষে স্ক্রোল করবে।

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

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

  constructor(private router: Router) { }

  ngOnInit() {
    const scrollLevels: { [navigationId: number]: number } = {};
    let lastId = 0;
    let restoredId: number;

    this.router.events.subscribe((event: Event) => {

      if (event instanceof NavigationStart) {
        scrollLevels[lastId] = window.scrollY;
        lastId = event.id;
        restoredId = event.restoredState ? event.restoredState.navigationId : undefined;
      }

      if (event instanceof NavigationEnd) {
        if (restoredId) {
          // Optional: Wrap a timeout around the next line to wait for
          // the component to finish loading
          window.scrollTo(0, scrollLevels[restoredId] || 0);
        } else {
          window.scrollTo(0, 0);
        }
      }

    });
  }

}

অসাধারণ. উইন্ডোর চেয়ে ডিভ স্ক্রোল করতে আমাকে কিছুটা কাস্টম সংস্করণ তৈরি করতে হয়েছিল, তবে এটি কার্যকর হয়েছে। একটি মূল পার্থক্য scrollTopবনাম ছিল scrollY
বিবিসিঞ্জার

4

নীচে দেখানো অনুসারে @ গুইলেহর্মি মাইরিলেস দ্বারা প্রদত্ত নিখুঁত উত্তর ছাড়াও , আপনি নীচের চিত্রের মতো মসৃণ স্ক্রোল যুক্ত করে আপনার প্রয়োগকে সামঞ্জস্য করতে পারেন

 import { Component, OnInit } from '@angular/core';
    import { Router, NavigationEnd } from '@angular/router';

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

        ngOnInit() {
            this.router.events.subscribe((evt) => {
                if (!(evt instanceof NavigationEnd)) {
                    return;
                }
                window.scrollTo(0, 0)
            });
        }
    }

তারপরে নীচে স্নিপেট যুক্ত করুন

 html {
      scroll-behavior: smooth;
    }

আপনার স্টাইলস CSS এ


1

আইফোন / আইওএস সাফারির জন্য আপনি একটি সেটটাইমআউট দিয়ে মোড়ানো করতে পারেন

setTimeout(function(){
    window.scrollTo(0, 1);
}, 0);

আমার ক্ষেত্রে এটিতে পৃষ্ঠা মোড়ানোর উপাদান সিএসএস সেট করা দরকার; height: 100vh + 1px;
টিউবিসি

1

হাই ছেলেরা এটি আমার জন্য কৌণিক 4 এ কাজ করে You আপনার কেবলমাত্র রাউটার চেঞ্জ-এ স্ক্রোল করার জন্য পিতামাতাকে উল্লেখ করতে হবে `

layout.component.pug

.wrapper(#outlet="")
    router-outlet((activate)='routerActivate($event,outlet)')

layout.component.ts

 public routerActivate(event,outlet){
    outlet.scrollTop = 0;
 }`

1
পাগ শিখতে বিরক্ত না করে আমার অলসতা ক্ষমা করুন, তবে আপনি কি এইচটিএমএল অনুবাদ করতে পারবেন?
কোডি বাগস্টিন

0

পছন্দ করুন তবে এই কোডটি হ্যাশ রাউটার বা অলস রাউটারে কাজ করে না। কারণ তারা অবস্থান পরিবর্তনগুলি ট্রিগার করে না। এটি চেষ্টা করতে পারেন:

private lastRouteUrl: string[] = []
  

ngOnInit(): void {
  this.router.events.subscribe((ev) => {
    const len = this.lastRouteUrl.length
    if (ev instanceof NavigationEnd) {
      this.lastRouteUrl.push(ev.url)
      if (len > 1 && ev.url === this.lastRouteUrl[len - 2]) {
        return
      }
      window.scrollTo(0, 0)
    }
  })
}


0

Routerনিজেই ব্যবহার করা এমন সমস্যার কারণ হয়ে দাঁড়াবে যা সামঞ্জস্যপূর্ণ ব্রাউজারের অভিজ্ঞতা বজায় রাখতে আপনি পুরোপুরি কাটিয়ে উঠতে পারবেন না। আমার মতে সর্বোত্তম পদ্ধতিটি হ'ল কেবল একটি কাস্টম ব্যবহার করা directiveএবং এটি ক্লিক করে স্ক্রোলটি পুনরায় সেট করতে দিন। এটি সম্পর্কে ভাল কথাটি হ'ল আপনি urlযদি ক্লিক করেন সেই একই সাথে থাকেন তবে পৃষ্ঠাটি শীর্ষেও ফিরে যাবে। এটি সাধারণ ওয়েবসাইটগুলির সাথে সামঞ্জস্যপূর্ণ। বেসিকটি directiveএরকম কিছু দেখতে পারে:

import {Directive, HostListener} from '@angular/core';

@Directive({
    selector: '[linkToTop]'
})
export class LinkToTopDirective {

    @HostListener('click')
    onClick(): void {
        window.scrollTo(0, 0);
    }
}

নিম্নলিখিত ব্যবহারের সাথে:

<a routerLink="/" linkToTop></a>

এটি বেশিরভাগ ব্যবহারের ক্ষেত্রে যথেষ্ট হবে তবে আমি কয়েকটি বিষয় কল্পনা করতে পারি যা এ থেকে উদ্ভূত হতে পারে:

  • কাজ করে না universalব্যবহারের কারণেwindow
  • পরিবর্তন সনাক্তকরণের উপর ছোট গতির প্রভাব, কারণ এটি প্রতিটি ক্লিকের মাধ্যমে ট্রিগার হয়
  • এই নির্দেশকে অক্ষম করার কোনও উপায় নেই

আসলে এই বিষয়গুলি পরাস্ত করা বেশ সহজ:

@Directive({
  selector: '[linkToTop]'
})
export class LinkToTopDirective implements OnInit, OnDestroy {

  @Input()
  set linkToTop(active: string | boolean) {
    this.active = typeof active === 'string' ? active.length === 0 : active;
  }

  private active: boolean = true;

  private onClick: EventListener = (event: MouseEvent) => {
    if (this.active) {
      window.scrollTo(0, 0);
    }
  };

  constructor(@Inject(PLATFORM_ID) private readonly platformId: Object,
              private readonly elementRef: ElementRef,
              private readonly ngZone: NgZone
  ) {}

  ngOnDestroy(): void {
    if (isPlatformBrowser(this.platformId)) {
      this.elementRef.nativeElement.removeEventListener('click', this.onClick, false);
    }
  }

  ngOnInit(): void {
    if (isPlatformBrowser(this.platformId)) {
      this.ngZone.runOutsideAngular(() => 
        this.elementRef.nativeElement.addEventListener('click', this.onClick, false)
      );
    }
  }
}

এটি সক্রিয় / নিষ্ক্রিয় করার সুবিধার্থে মৌলিক ক্ষেত্রে একই ব্যবহার সহ বেশিরভাগ ব্যবহারের ক্ষেত্রে বিবেচনা করে:

<a routerLink="/" linkToTop></a> <!-- always active -->
<a routerLink="/" [linkToTop]="isActive"> <!-- active when `isActive` is true -->

বিজ্ঞাপন, আপনি বিজ্ঞাপন করতে চান না পড়ুন

ব্রাউজার passiveইভেন্টগুলি সমর্থন করে কিনা তা পরীক্ষা করার জন্য আরেকটি উন্নতি করা যেতে পারে । এটি কোডটিকে আরও কিছুটা জটিল করে তুলবে এবং আপনি যদি নিজের কাস্টম দিকনির্দেশনা / টেম্পলেটগুলিতে এই সমস্ত প্রয়োগ করতে চান তবে কিছুটা অস্পষ্ট is এই কারণেই আমি একটি ছোট লাইব্রেরি লিখেছিলাম যা আপনি এই সমস্যাগুলি সমাধান করতে ব্যবহার করতে পারেন। উপরের মতো একই কার্যকারিতা এবং যুক্ত passiveইভেন্টের সাথে, আপনি যদি ng-event-optionsলাইব্রেরিটি ব্যবহার করেন তবে আপনি এটিতে আপনার নির্দেশিকা পরিবর্তন করতে পারেন can click.pnbশ্রোতার ভিতরে যুক্তিটি রয়েছে :

@Directive({
    selector: '[linkToTop]'
})
export class LinkToTopDirective {

    @Input()
    set linkToTop(active: string|boolean) {
        this.active = typeof active === 'string' ? active.length === 0 : active;
    }

    private active: boolean = true;

    @HostListener('click.pnb')
    onClick(): void {
      if (this.active) {
        window.scrollTo(0, 0);
      }        
    }
}

0

এটি হ্যাশ নেভিগেশন সহ সমস্ত নেভিগেশন পরিবর্তনের জন্য আমার পক্ষে সবচেয়ে ভাল কাজ করেছে

constructor(private route: ActivatedRoute) {}

ngOnInit() {
  this._sub = this.route.fragment.subscribe((hash: string) => {
    if (hash) {
      const cmp = document.getElementById(hash);
      if (cmp) {
        cmp.scrollIntoView();
      }
    } else {
      window.scrollTo(0, 0);
    }
  });
}

0

এই কোডের পেছনের মূল ধারণাটি হ'ল সমস্ত ভিজিট করা url বরাবর একটি অ্যারেতে সম্পর্কিত স্ক্রোলওয়াই ডেটা সহ। প্রতিবার কোনও ব্যবহারকারী কোনও পৃষ্ঠা (নেভিগেশনস্টার্ট) ত্যাগ করলে এই অ্যারেটি আপডেট হয়। যখনই কোনও ব্যবহারকারী কোনও নতুন পৃষ্ঠাতে প্রবেশ করতে পারে (নেভিগেশনএন্ড), আমরা ওয়াই অবস্থানটি পুনরুদ্ধার করার সিদ্ধান্ত নিয়েছি বা আমরা কীভাবে এই পৃষ্ঠায় পাব তার উপর নির্ভর করে না। যদি কোনও পৃষ্ঠায় রেফারেন্স ব্যবহার করা হত তবে আমরা 0 এ স্ক্রোল করব browser ব্রাউজারের পিছনে / ফরোয়ার্ড বৈশিষ্ট্যগুলি ব্যবহার করা হলে আমরা আমাদের অ্যারেতে সংরক্ষিত ওয়াই তে স্ক্রোল করব। আমার ইংরেজীর জন্য দুঃখিত :)

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Location, PopStateEvent } from '@angular/common';
import { Router, Route, RouterLink, NavigationStart, NavigationEnd, 
    RouterEvent } from '@angular/router';
import { Subscription } from 'rxjs/Subscription';

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

  private _subscription: Subscription;
  private _scrollHistory: { url: string, y: number }[] = [];
  private _useHistory = false;

  constructor(
    private _router: Router,
    private _location: Location) {
  }

  public ngOnInit() {

    this._subscription = this._router.events.subscribe((event: any) => 
    {
      if (event instanceof NavigationStart) {
        const currentUrl = (this._location.path() !== '') 
           this._location.path() : '/';
        const item = this._scrollHistory.find(x => x.url === currentUrl);
        if (item) {
          item.y = window.scrollY;
        } else {
          this._scrollHistory.push({ url: currentUrl, y: window.scrollY });
        }
        return;
      }
      if (event instanceof NavigationEnd) {
        if (this._useHistory) {
          this._useHistory = false;
          window.scrollTo(0, this._scrollHistory.find(x => x.url === 
          event.url).y);
        } else {
          window.scrollTo(0, 0);
        }
      }
    });

    this._subscription.add(this._location.subscribe((event: PopStateEvent) 
      => { this._useHistory = true;
    }));
  }

  public ngOnDestroy(): void {
    this._subscription.unsubscribe();
  }
}

0

window.scrollTo()5 কৌণিক ক্ষেত্রে আমার জন্য কাজ করে না, তাই আমি document.body.scrollTopযেমন ব্যবহার করেছি ,

this.router.events.subscribe((evt) => {
   if (evt instanceof NavigationEnd) {
      document.body.scrollTop = 0;
   }
});

0

আপনি যদি একই রুট দিয়ে বিভিন্ন উপাদান লোড করছেন তবে আপনি একই জিনিসটি অর্জন করতে ভিউপোর্টস্রোলার ব্যবহার করতে পারেন।

import { ViewportScroller } from '@angular/common';

constructor(private viewportScroller: ViewportScroller) {}

this.viewportScroller.scrollToPosition([0, 0]);

0

উইন্ডো স্ক্রোল শীর্ষে
উভয়ই উইন্ডো.পৃষ্ঠাঅফসেট এবং ডকুমেন্ট.ডোকামেন্টএলমেন্ট.স্ক্রোলটপ সমস্ত ক্ষেত্রে একই ফলাফল প্রদান করে। উইন্ডো.পৃষ্ঠাঅফসেট IE 9 এর নীচে সমর্থিত নয়।

app.component.ts

import { Component, HostListener, ElementRef } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  isShow: boolean;
  topPosToStartShowing = 100;

  @HostListener('window:scroll')
  checkScroll() {

    const scrollPosition = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;

    console.log('[scroll]', scrollPosition);

    if (scrollPosition >= this.topPosToStartShowing) {
      this.isShow = true;
    } else {
      this.isShow = false;
    }
  }

  gotoTop() {
    window.scroll({ 
      top: 0, 
      left: 10, 
      behavior: 'smooth' 
    });
  }
}

app.component.html

<style>
  p {
  font-family: Lato;
}

button {
  position: fixed;
  bottom: 5px;
  right: 5px;
  font-size: 20px;
  text-align: center;
  border-radius: 5px;
  outline: none;
}
  </style>
<p>
  Lorem ipsum dolor sit, amet consectetur adipisicing elit. Minus, repudiandae quia. Veniam amet fuga, eveniet velit ipsa repudiandae nemo? Sit dolorem itaque laudantium dignissimos, rerum maiores nihil ad voluptates nostrum.
</p>
<p>
  Lorem ipsum dolor sit, amet consectetur adipisicing elit. Minus, repudiandae quia. Veniam amet fuga, eveniet velit ipsa repudiandae nemo? Sit dolorem itaque laudantium dignissimos, rerum maiores nihil ad voluptates nostrum.
</p>
<p>
  Lorem ipsum dolor sit, amet consectetur adipisicing elit. Minus, repudiandae quia. Veniam amet fuga, eveniet velit ipsa repudiandae nemo? Sit dolorem itaque laudantium dignissimos, rerum maiores nihil ad voluptates nostrum.
</p>
<p>
  Lorem ipsum dolor sit, amet consectetur adipisicing elit. Minus, repudiandae quia. Veniam amet fuga, eveniet velit ipsa repudiandae nemo? Sit dolorem itaque laudantium dignissimos, rerum maiores nihil ad voluptates nostrum.
</p>
<p>
  Lorem ipsum dolor sit, amet consectetur adipisicing elit. Minus, repudiandae quia. Veniam amet fuga, eveniet velit ipsa repudiandae nemo? Sit dolorem itaque laudantium dignissimos, rerum maiores nihil ad voluptates nostrum.
</p>
<p>
  Lorem ipsum dolor sit, amet consectetur adipisicing elit. Minus, repudiandae quia. Veniam amet fuga, eveniet velit ipsa repudiandae nemo? Sit dolorem itaque laudantium dignissimos, rerum maiores nihil ad voluptates nostrum.
</p>
<p>
  Lorem ipsum dolor sit, amet consectetur adipisicing elit. Minus, repudiandae quia. Veniam amet fuga, eveniet velit ipsa repudiandae nemo? Sit dolorem itaque laudantium dignissimos, rerum maiores nihil ad voluptates nostrum.
</p>
<p>
  Lorem ipsum dolor sit, amet consectetur adipisicing elit. Minus, repudiandae quia. Veniam amet fuga, eveniet velit ipsa repudiandae nemo? Sit dolorem itaque laudantium dignissimos, rerum maiores nihil ad voluptates nostrum.
</p>

<button *ngIf="isShow" (click)="gotoTop()">👆</button>
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.