如何检测滚动到html元素的底部

Posted

技术标签:

【中文标题】如何检测滚动到html元素的底部【英文标题】:How to detect scroll to bottom of html element 【发布时间】:2017-04-01 13:51:54 【问题描述】:

我有这个通过 Id 引用的元素:

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

我需要在浏览器到达元素底部时进行监听。

如何做到这一点?

【问题讨论】:

这个 Angular 2 模块可以帮助你npmjs.com/package/angular2-infinite-scroll 【参考方案1】:

您可以使用一个跟踪容器滚动事件的 observable 来做到这一点。

或者您可以为正在侦听滚动事件的组件创建一个主机侦听器。请看看这个SO question。 (我还没有使用主机监听器对其进行测试,但这应该可以。)

将以下代码添加到您的组件中以实现可观察的方法(我已经从 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');
      
    );
  

更新

另一种可能是最好的方法是为您的跟踪逻辑创建一个指令。然后就可以很方便的使用HostListener绑定滚动事件了。

打字稿代码:

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

组件中的标记(添加指令)

<div id="th-infinite-scroll-tracker" style="overflow-y:scroll; height: 500px;" scrollTracker>
  .... your container with scrollbar ...
</div>

【讨论】:

Here 是主机监听器指令的演示,因此您可以看到监听器的运行情况。 滚动事件对我不起作用,我使用的是 Angular 6,如果我用 window:scroll 更改它,它会起作用。【参考方案2】:

我认为您要做的就是检测滚动的位置。

@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
 

别忘了从 @angular/core 导入 HostListener。

【讨论】:

它正在工作,但我想在特定的部分使用 ID 或类上滚动检测。那么我该如何检测呢? 它适用于正文滚动,不适用于特定段或 div。 嘿@KMRifatulalom 你可以通过ID访问它来检测div的滚动 前。 var elem = document.getElementById("speakers_list"); var pos = elem.scrollTop + elem.offsetHeight; var max = elem.scrollHeight; 使用 var prevPos(default: 0) 并将其与 pos 进行比较。 ``` if (prevPos > pos) /* 向下滚动函数 */ prevPos = pos; ```【参考方案3】:

您可以通过以下方式检查用户是否滚动到底部...

HTML 文件

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

打字稿文件

onScroll(event: any) 
    // visible height + pixel scrolled >= total height 
    if (event.target.offsetHeight + event.target.scrollTop >= event.target.scrollHeight) 
      console.log("End");
    

【讨论】:

必须将 === 更改为 &gt;=,因为当完全滚动到元素底部时,左侧的等式更大。 我不需要HostListener,只需要(scroll)='onScroll($event)'。超级简单。 它不需要 HostListener 简单的功能也可以确保你使用 isPlatformBrowser 和它同时 HostListener 滚动事件不断刷新整个 Angular 对象,这使得整个应用程序很重。不要在 HostListener 中使用滚动事件。 @NarottamGoyal 当我到达终点时,我进行了服务调用并将数据附加到表中,但滚动条仍然在最后,它一次又一次地进行服务调用。你能帮忙吗? 对我来说多次触发,这对我来说是一个交易破坏者。不得不使用AWolf的解决方案【参考方案4】:

我现在确实在研究这个,发现这是“me”最通用的用例。

正如 YASH DAVE 提到的,使用主机侦听器是 Angular 'onScroll' 实现的最佳选择。但是,“Window: Scroll”不适用于我的用例(在仪表板中注入的表格)。所以我很幸运这样做


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

说明:

基本上,通用“滚动”监听宿主元素上发生的滚动事件。 通过 $event.target 将触发滚动事件的元素引用传递给我的 onScroll(elem) 方法 然后我获取元素引用并确定 offsetHeight 和 ScrollTop 是否大于 scrollHeight (是的,这与其他人的实现方式不同) 参考: @ 987654322@ 然后繁荣,享受。 注意:如果您只需要一个,我不能强调这一点简单的解决方案只需在特定元素

另外,查看 This 以了解有关offsetHeight、clientHeight、scrollHeight 的见解。

【讨论】:

【参考方案5】:

试试这个,它会起作用的

@HostListener('body:scroll', ['$event'])

【讨论】:

以上是关于如何检测滚动到html元素的底部的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 中,当用户滚动浏览 WKWebView 时,如何检测屏幕上可见的 html 元素?

jQuery滚动到元素的底部而不是顶部

如何滚动到元素的底部?

禁止蒙层底部页面跟随滚动

创建新消息/元素时如何自动滚动到div的底部

前端必知:如何判断元素出现在视口内(性能优化涉及)