How to detect scroll to bottom of html element

后端 未结 4 789
一生所求
一生所求 2020-12-02 11:42

I have this element that I\'m referencing by Id:

    let infiniteScrollElement = document.getElementById(\'th-infinite-scroll-tracker\');

I

相关标签:
4条回答
  • 2020-12-02 11:48

    You could check whether the user has scrolled to the bottom or not in the below way...

    Html file

    <div (scroll)="onScroll($event)">
        ...
        ...
    </div>
    

    typescript file

    import { Component, HostListener } from '@angular/core';
        ...
        ...
    @HostListener('scroll', ['$event'])
    onScroll(event: any) {
        // visible height + pixel scrolled >= total height 
        if (event.target.offsetHeight + event.target.scrollTop >= event.target.scrollHeight) {
          console.log("End");
        }
    }
    
    0 讨论(0)
  • 2020-12-02 11:54

    I think that all you want to do is detect the position of scroll.

    @HostListener("window:scroll", ["$event"])
    onWindowScroll() {
    //In chrome and some browser scroll is given to body tag
    let pos = (document.documentElement.scrollTop || document.body.scrollTop) + document.documentElement.offsetHeight;
    let max = document.documentElement.scrollHeight;
    // pos/max will give you the distance between scroll bottom and and bottom of screen in percentage.
     if(pos == max )   {
     //Do your action here
     }
    }
    

    Also don't forget to import HostListener from @angular/core.

    0 讨论(0)
  • 2020-12-02 11:57

    You could do this with an observable that's tracking the scroll event of your container.

    Or you could create a host listener for your component that's listening for the scroll event. Please have a look at this SO question. (I haven't tested it with a host listener but that should work.)

    Add the following code to your component for observable approach (I've copied some of the code from this blog post. ):

      ngOnInit() {
        /*
         * Create the observable from an event, in this case, the window scroll event
         * then map each event so we can get a new value from it
         * i.e. over time, we are just dealing with a collection:
         * (map [e1, e2, e3, ...]) -> [t1, t2, t3, ...]
         */
        let tracker = document.getElementById('th-infinite-scroll-tracker');
    
        let windowYOffsetObservable = Observable.fromEvent(tracker, 'scroll').map(() => {
          // I don't actually care about the event, I just need to get the window offset (scroll position)
          return tracker.scrollTop;
        });
    
        // subscribe to our Observable so that for each new item, our callback runs
        // this is our event handler
        let scrollSubscription = windowYOffsetObservable.subscribe((scrollPos) => {
          let limit = tracker.scrollHeight - tracker.clientHeight;
          console.log(scrollPos, limit);
          if (scrollPos === limit) {
            alert('end reached');
          }
        });
      }
    

    Update

    Another way and probably the best would be to create a directive for your tracking logic. Then you can easily use HostListener to bind to the scroll event.

    Typescript code:

    import {
      Directive, HostListener
    }
    from '@angular/core';
    
    @Directive({
      selector: '[scrollTracker]'
    })
    export class ScrollTrackerDirective {
      @HostListener('scroll', ['$event']);
    
      onScroll(event) {
        // do tracking
        // console.log('scrolled', event.target.scrollTop);
        // Listen to click events in the component
        let tracker = event.target;
    
        let limit = tracker.scrollHeight - tracker.clientHeight;
        console.log(event.target.scrollTop, limit);
        if (event.target.scrollTop === limit) {
          alert('end reached');
        }
      }
    
      constructor() {}
    }
    

    Markup in your component (add your directive)

    <div id="th-infinite-scroll-tracker" style="overflow-y:scroll; height: 500px;" scrollTracker>
      .... your container with scrollbar ...
    </div>
    
    0 讨论(0)
  • 2020-12-02 11:59

    I am literally working on this now and found that this is the most versatile use case for "me."

    As YASH DAVE mentioned, using a Host Listener is your best bet for an Angular 'onScroll' implementation. However, 'Window: Scroll' didn't work for my use case (a table injected within a Dashboard). So I had luck doing this


    @HostListener('scroll', ['$event.target'])
     onScroll(elem){
      if(( elem.offsetHeight + elem.scrollTop) >=  elem.scrollHeight) {
         console.log("It's Lit");
      }
    }'
    

    CSS:

    :host {
         display: block;
         max-height: 700px;
         width: 100%;
         overflow-y: scroll;
         scroll-behavior: auto;
     }
    

    Explanation:

    • Basically the generic "scroll" listens for the scroll event occurring on the host element.
    • passes the element reference that triggered the scroll event via $event.target to my onScroll(elem) method
    • Then I take the element reference and determine if the offsetHeight and ScrollTop is greater than the scrollHeight (yes this is different then how others have implemented this) reference: mVChr's Implementation
    • Then boom, enjoy.
    • Note: If you just need a, and I can't stress this enough, simple solution just add a (scroll) event listener on the particular element

    Additionally, review This for an insight on offsetHeight, clientHeight, scrollHeight.

    0 讨论(0)
提交回复
热议问题