We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
interSection Observer 提供了一种异步检测目标元素与指定祖先元素相交情况变化的方法;基于这个API,最常见的两个使用场景是:
传统的做法都是绑定scroller事件,滚动过程通过Element.getBoundingClientRect()计算是否出现在可视区,然后加载图片,然而这些都是在主线程频繁触发,会影响性能;
Element.getBoundingClientRect()
import React, { useState, useEffect, useRef } from 'react'; import { imgs } from './imgs.ts' //这个文件会返回一个很长的图片列表 export default () => { useEffect(() => { const interSectionObserver = new IntersectionObserver(entries => { // 当目标元素与视窗(默认的祖先元素)交叉超过阈值(默认为0)时的回调,entries是所有观测的目标元素 entries.forEach(item => { if (item.isIntersecting) { // true表示超过交叉阈值,取dataset.src复制给src,实现图片加载 const imgDom = item.target const imgSrc = imgDom.dataset.src imgDom.src = imgSrc interSectionObserver.unobserve(imgDom) // 图片加载完毕之后,取消观测该元素,否则来回滚动会继续触发; } }) }, { rootMargin: "350px 0px" // 这个会使得根元素的矩形大小上下各增加350px; 实现图片没有出现在屏幕可视区,但是开始加载; }) Array.from(document.querySelectorAll('img')).forEach(dom => { interSectionObserver.observe(dom) // 找到所有的img元素,并观测; }) }, []) return (<div style={{ height: "600px", overflow: "scroll" }}> { imgs.map((item, index) => { return <div style={{ 'justifyContent': "center" }} key={item}> {/** 先把图片资源存储在data-src中 */} <img data-src={item} style={{ width: "300px", height: "165px", margin: "20px" }} /> <span>{index}</span> </div> }) } </div>) }
这个场景在移动端会比较常见,滚定到底部实现自动分页,一般的做法也是绑定scoller事件,判断距离底部一定的值时发接口。问题和图片懒加载是一样的,利用IntersectionObserver就可以改善很多,在最底部放一个元素,观测该元素的交叉状况即可实现分页;
scoller
IntersectionObserver
import React, { useState, useEffect, useRef } from 'react'; const bgColors = ['#4e61d4', '#ccc', '#999', 'pink', 'yellow'] const generateBlock = (counts: Number) => { return new Array(counts).fill(0).map(() => { const backgroundColor = bgColors[Math.floor(Math.random() * bgColors.length)] return <div style={{ height: "50px", margin: "20px 0", backgroundColor }} /> }) } export default function () { const [blocks, setBlocks] = useState(generateBlock(10)); const footerRef = useRef('') useEffect(() => { const interSectionObserver = new IntersectionObserver((enteries) => { // 可见 if (enteries[0].isIntersecting) { addblocks(10) //增加10个背景色随机的块(模拟分页) } },{ rootMargin:"50px 0px" }); if (footerRef.current) { interSectionObserver.observe(footerRef.current) } }, []) const addblocks = (counts: Number) => { setBlocks((prevBlocks) => ([...prevBlocks, ...generateBlock(counts)])) } return ( <> <div>无线向下滚动</div> {[...blocks]} <div ref={footerRef} style={{ height: "1px" }}>footer</div> </> ); }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
简介
interSection Observer 提供了一种异步检测目标元素与指定祖先元素相交情况变化的方法;基于这个API,最常见的两个使用场景是:
下边具体看看这两个场景的具体例子;
图片懒加载
传统的做法都是绑定scroller事件,滚动过程通过
Element.getBoundingClientRect()
计算是否出现在可视区,然后加载图片,然而这些都是在主线程频繁触发,会影响性能;无限滚动
这个场景在移动端会比较常见,滚定到底部实现自动分页,一般的做法也是绑定
scoller
事件,判断距离底部一定的值时发接口。问题和图片懒加载是一样的,利用IntersectionObserver
就可以改善很多,在最底部放一个元素,观测该元素的交叉状况即可实现分页;The text was updated successfully, but these errors were encountered: