原由
之前本身在运用这类网站时,常常看到无穷加载的结果。
本日恰好看到了getBoundingClientRect
这个Api,就想着碰运气怎样完成Infinite scroll
的结果。
道理
在须要无穷加载的列表底部,埋下一个隐蔽元素。
当不停滑动时,隐蔽元素将出如今视窗(viewport)里,也就意味着当前阅读的列表已究竟部了。
这时候就须要举行列表加载。
也许的HTML构造以下:
<div>
<ul class="article-list">
<li>我是文章</li>
<li>我是文章</li>
<li>我是文章</li>
<li>我是文章</li>
<li>我是文章</li>
</ul>
<div class="infinite-scroll-signal"></div>
</div>
也就是:滑动列表 => 隐蔽的无穷加载指示器出如今视图 => 最先加载
那末重点就是检测隐蔽的无穷加载指示器是不是出如今视图窗口。
还好,我们有getBoundingClientRect
这个Api。
getBoundingClientRect
经由过程查阅MDN,得知:
Element.getBoundingClientRect()要领返回元素的大小及其相对于视口的位置。而除了 width 和 height 外的属性都是相对于视口的左上角位置而言的。
至于兼容性,一片绿,能够放心运用。
<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 对象
getBoundingClientRect()要领的返回值是一个 DOMRect 对象,这个对象是由该元素的 getClientRects() 要领返回的一组矩形的鸠合, 即:是与该元素相干的CSS 边框鸠合 。
对象的属性以下图所示:
个中的 top, left, bottom, right
均是元素本身相对于视图左上角而言的。
就top, left
属性而言,很好明白。而bottom, right
则一最先搞的有点懵,背面经由过程devtools视察,发明bottom
是元素的最底部相对于视图窗口左上角而言的,而right
则是元素的最右边相对于视图窗口左上角而言的。
个中right-left
为元素的宽度,bottom - top
则是元素的高度。
检测元素是不是涌现于视图窗口中
在这里,有两种状况,一个是元素是不是涌现于视图窗口中,另一种则是元素是不是完整涌现于视图窗口中。
两种状况的区分在于一个是部份涌现,一个是完整涌现。
下面我把两种状况都写出来:
部份出如今视图窗口中
function checkIsPartialVisible (element) {
const rect = element.getBoundingClientRect()
const {
top,
left,
bottom,
right
} = rect
const isPartialVisible = top >= 0 && left >= 0
return isPartialVisible
}
悉数涌现于视图窗口中:
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
}
那末题目来了:我们究竟选用那种呢?
从无穷加载这个营业场景动身,埋在列表最下边的加载触发器都异常小且不可见,因而引荐选用第二种,也就是完整涌现于视图窗口的体式格局。
至于第一种,更适合检测该元素是不是已出如今视图窗口,但并不请求悉数涌现的状况。
实战
详细能够看我在jsfiddle上写的demo:
无穷加载实例
后续
后续更多的则是一些机能优化的事变,比方debounce或许throttle来削减scroll事宜挪用次数,到场ajax加载,loading indicator等。
那些都是属于详细的营业范围了,这儿不做议论。