JavaScript implements infinite loading of lists

origin

When I used this kind of website before, I often saw the infinite loading effect.
I happened to see getBoundingClientRectthis API today and wanted to try it out to see how it works Infinite scroll.

principle

Bury a hidden element at the bottom of the list that needs to be infinitely loaded.
When sliding continuously, hidden elements will appear in the viewport, which means that the currently browsed list has reached the bottom.
At this time, you need to load the list.
The approximate HTML structure is as follows:

<div>
  <ul class="article-list">
    <li>我是文章</li>
    <li>我是文章</li>
    <li>我是文章</li>
    <li>我是文章</li>
    <li>我是文章</li>
  </ul>
  <div class="infinite-scroll-signal"></div>
</div>

That is: sliding list => hidden infinite loading indicator appears in view => starts loading

Then the point is to detect whether the hidden infinite loading indicator appears in the view window.
Fortunately, we have getBoundingClientRectthis API.

getBoundingClientRect

By consulting MDN, I learned:

The Element.getBoundingClientRect() method returns the size of the element and its position relative to the viewport. Properties other than width and height are relative to the upper left corner of the viewport.

As for compatibility, it’s all green and you can use it with confidence.

<p class="ciu_embed" data-feature="getboundingclientrect" data-periods="future_1,current,past_1,past_2">
Can I Use getboundingclientrect? Data on support for the getboundingclientrect feature across the major browsers from caniuse.com.
</p>

DOMRect object

The return value of the getBoundingClientRect() method is a DOMRect object, which is a collection of rectangles returned by the element's getClientRects() method, that is, a collection of CSS borders related to the element.

The properties of the object are as shown below:

All of them  top, left, bottom, right are relative to the element itself relative to the upper left corner of the view.
In top, leftterms of properties, it's easy to understand. bottom, rightI was a little confused at first, but after observing through devtools, I found that bottomthe bottommost part of the element is relative to the upper left corner of the view window, and rightthe rightmost part of the element is relative to the upper left corner of the view window.
where right-leftis the width of the element, bottom - topand is the height of the element.

Detect whether an element appears in the view window

Here, there are two situations, one is whether the element appears in the view window, and the other is whether the element appears completely in the view window.
The difference between the two situations is that one appears partially and the other appears completely.

Below I write out both situations:

  1. section appears in the view window

function checkIsPartialVisible (element) {
  const rect = element.getBoundingClientRect()
  const {
    top,
    left,
    bottom,
    right
  } = rect
  const isPartialVisible = top >= 0 && left >= 0
  return isPartialVisible
}
  1. All appear in the view window:

function checkIsTotalVisible (element) {
  const rect = element.getBoundingClientRect()
  const {
    top,
    left,
    bottom,
    right
  } = rect
  const isTotalVisible = (
    top >= 0
    &&
    left >= 0
    &&
    bottom < document.documentElement.clientHeight
    &&
    right < document.documentElement.clientWidth
  )
  return isTotalVisible
}

So the question is: Which one should we choose?
Starting from the business scenario of infinite loading, the loading triggers buried at the bottom of the list are very small and invisible, so it is recommended to use the second method, which is to appear completely in the view window.
As for the first type, it is more suitable for detecting whether the element has appeared in the view window, but does not require all occurrences.

Follow-up

What follows is more performance optimization, such as debounce or throttle to reduce the number of scroll event calls, adding ajax loading, loading indicator, etc.
Those are specific business scopes and will not be discussed here.

Guess you like

Origin blog.csdn.net/qq_41221596/article/details/132837953