useInViewport

簡介

1 .觀察元素是否在可見區(qū)域
2 .使用場景:

1 .圖片懶加載-當(dāng)圖片滾動到可見位置的時候才加載
2 .內(nèi)容無限滾動-用戶滾動到接近內(nèi)容底部時直接加載更多
3 .檢測廣告的曝光率,廣告是否被看到了
4 .用戶看到某個區(qū)域時執(zhí)行任務(wù)或播放動畫

3 .傳統(tǒng)實現(xiàn):監(jiān)聽scroll事件,調(diào)用目標元素的getBoundingClientRect().得到相對于視口左上角的坐標,在判斷是否在視口之內(nèi).但是觸發(fā)非常頻繁,這樣計算就會有性能問題

4 .最簡單例子

import React,{useRef} from 'react'
import {useInViewport} from 'ahooks'
export default function Drag(props){
    const ref=useRef()
    const [inViewport,ratio]=useInViewport(ref,{
        threshold:0.1,
    })
    console.log(inViewport,ratio)
    return (
        <div>
            <div style={{ width: 300, height: 300, overflow: 'scroll', border: '1px solid',position:'absolute',top:'100px' }}>
                scroll here
                <div style={{ height: 800 }}>
                <div
                    ref={ref}
                    style={{
                    border: '1px solid',
                    height: 100,
                    width: 100,
                    textAlign: 'center',
                    marginTop: 80,
                    }}
                >
                    observer dom
                </div>
                </div>
            </div>
            {/* <div style={{ marginTop: 16, color: inViewport ? '#87d068' : '#f50' }}>
                inViewport: {inViewport ? 'visible' : 'hidden'}
            </div> */}
        </div>
    )
}

原生實現(xiàn)

1 .IntersectionObserver的實現(xiàn)屑咳,應(yīng)該采用requestIdleCallback()虚汛,即只有線程空閑下來侦厚,才會執(zhí)行觀察器大脉。這意味著浸卦,這個觀察器的優(yōu)先級非常低,只在其他任務(wù)執(zhí)行完颁褂,瀏覽器有了空閑才會執(zhí)行

import React,{useEffect,useState} from 'react'
export default function Drag(props){
    const [url,setUrl]=useState('222')
    useEffect(()=>{
        const io=new IntersectionObserver((entries)=>{
            entries.forEach((change)=>{
                // let [container,visible]=change
                // 這樣操作還不行

                if(change.intersectionRatio<=0)return
                // 消失
                
                let container=change.target
                let visible=change.isVisible
                console.log('被觀察的目標出現(xiàn)在了視口里面')

                // 可以加載更多的數(shù)據(jù),實現(xiàn)無限滾動的操作.這樣做的虛擬列表,我們連右邊的滾動條也可以自己實現(xiàn),不用瀏覽器自帶的版本,虛擬列表也可以這么做.因為瀏覽器的長度列表是完全靠高度撐起來的,最高是3千萬的px.有點離譜.感覺創(chuàng)建這么高的div應(yīng)該也會耗時間吧.

                // 可以更換圖片

                // 注意這里是每次出現(xiàn)都觸發(fā),但其實我們應(yīng)該是這個機制只觸發(fā)一次
            })
        },{})
        io.observe(document.getElementById('target'),{
            threshold:[0.5,1],
            // 只有出現(xiàn)的時候才觸發(fā)函數(shù),也就是目標元素出現(xiàn)了0.5的時候就會觸發(fā)函數(shù)u
            root:document.getElementById('parent'),
            // 觸發(fā)檢測的根元素
        })
        
    },[])
    
    return (
        <div>
            <div style={{ width: 300, height: 300, overflow: 'scroll', border: '1px solid',position:'absolute',top:'100px'}}
            id="parent"
            >
                <div style={{ height: 800 }}>
                    這是一個很長的占位操作
                </div>
                <div
                    style={{
                    border: '1px solid',
                    height: 100,
                    width: 100,
                    textAlign: 'center',
                    marginTop: 80,
                    }}
                    id='target'
                >
                    observer dom{url}
                </div>
            </div>
            {/* <div style={{ marginTop: 16, color: inViewport ? '#87d068' : '#f50' }}>
                inViewport: {inViewport ? 'visible' : 'hidden'}
            </div> */}
        </div>
    )
}

圖片懶加載的實現(xiàn)效果

1 .img不是先來默認圖片故黑,而是一開始都沒有地址

img{visibility:hidden}
img[src]{
  visibility:visible
}
<img />

2 .注意這是沒有src="",有的瀏覽器空值都會發(fā)出請求

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末擅憔,一起剝皮案震驚了整個濱河市鸵闪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌暑诸,老刑警劉巖蚌讼,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辟灰,死亡現(xiàn)場離奇詭異,居然都是意外死亡篡石,警方通過查閱死者的電腦和手機芥喇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凰萨,“玉大人继控,你說我怎么就攤上這事∨志欤” “怎么了武通?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長珊搀。 經(jīng)常有香客問我冶忱,道長,這世上最難降的妖魔是什么境析? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任囚枪,我火速辦了婚禮,結(jié)果婚禮上劳淆,老公的妹妹穿的比我還像新娘链沼。我一直安慰自己,他們只是感情好沛鸵,可當(dāng)我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布括勺。 她就那樣靜靜地躺著,像睡著了一般谒臼。 火紅的嫁衣襯著肌膚如雪朝刊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天蜈缤,我揣著相機與錄音,去河邊找鬼冯挎。 笑死底哥,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的房官。 我是一名探鬼主播趾徽,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼翰守!你這毒婦竟也來了孵奶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤蜡峰,失蹤者是張志新(化名)和其女友劉穎了袁,沒想到半個月后朗恳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡载绿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年粥诫,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片崭庸。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡怀浆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出怕享,到底是詐尸還是另有隱情执赡,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布函筋,位于F島的核電站沙合,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏驻呐。R本人自食惡果不足惜灌诅,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一含末、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧佣盒,春花似錦挎袜、人聲如沸肥惭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蜜葱。三九已至全景,卻和暖如春牵囤,著一層夾襖步出監(jiān)牢的瞬間爸黄,已是汗流浹背揭鳞。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工炕贵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人野崇。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓称开,卻偏偏與公主長得像,于是被迫代替她去往敵國和親乓梨。 傳聞我的和親對象是個殘疾皇子清酥,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容