如何判斷一個(gè)元素是否在可視區(qū)域中?
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
一、用途可視區(qū)域即我們?yōu)g覽網(wǎng)頁(yè)的設(shè)備肉眼可見(jiàn)的區(qū)域,如下圖 在日常開(kāi)發(fā)中,我們經(jīng)常需要判斷目標(biāo)元素是否在視窗之內(nèi)或者和視窗的距離小于一個(gè)值(例如 100 px),從而實(shí)現(xiàn)一些常用的功能,例如:
二、實(shí)現(xiàn)方式判斷一個(gè)元素是否在可視區(qū)域,我們常用的有三種辦法:
offsetTop、scrollTop
下面再來(lái)了解下
這里可以看到 最后,關(guān)于
注意
下面再看看如何實(shí)現(xiàn)判斷: 公式如下: el.offsetTop - document.documentElement.scrollTop <= viewPortHeight 代碼實(shí)現(xiàn): function isInViewPortOfOne (el) { // viewPortHeight 兼容所有瀏覽器寫(xiě)法 const viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight const offsetTop = el.offsetTop const scrollTop = document.documentElement.scrollTop const top = offsetTop - scrollTop return top <= viewPortHeight } getBoundingClientRect返回值是一個(gè) const target = document.querySelector('.target'); const clientRect = target.getBoundingClientRect(); console.log(clientRect); // { // bottom: 556.21875, // height: 393.59375, // left: 333, // right: 1017, // top: 162.625, // width: 684 // } 屬性對(duì)應(yīng)的關(guān)系圖如下所示: 當(dāng)頁(yè)面發(fā)生滾動(dòng)的時(shí)候, 如果一個(gè)元素在視窗之內(nèi)的話,那么它一定滿足下面四個(gè)條件:
實(shí)現(xiàn)代碼如下: function isInViewPort(element) { const viewWidth = window.innerWidth || document.documentElement.clientWidth; const viewHeight = window.innerHeight || document.documentElement.clientHeight; const { top, right, bottom, left, } = element.getBoundingClientRect(); return ( top >= 0 && left >= 0 && right <= viewWidth && bottom <= viewHeight ); } Intersection Observer
使用步驟主要分為兩步:創(chuàng)建觀察者和傳入被觀察者 創(chuàng)建觀察者const options = { // 表示重疊面積占被觀察者的比例,從 0 - 1 取值, // 1 表示完全被包含 threshold: 1.0, root:document.querySelector('#scrollArea') // 必須是目標(biāo)元素的父級(jí)元素 }; const callback = (entries, observer) => { ....} const observer = new IntersectionObserver(callback, options); 通過(guò) 關(guān)于 // 上段代碼中被省略的 callback const callback = function(entries, observer) { entries.forEach(entry => { entry.time; // 觸發(fā)的時(shí)間 entry.rootBounds; // 根元素的位置矩形,這種情況下為視窗位置 entry.boundingClientRect; // 被觀察者的位置舉行 entry.intersectionRect; // 重疊區(qū)域的位置矩形 entry.intersectionRatio; // 重疊區(qū)域占被觀察者面積的比例(被觀察者不是矩形時(shí)也按照矩形計(jì)算) entry.target; // 被觀察者 }); }; 傳入被觀察者通過(guò) const target = document.querySelector('.target'); observer.observe(target); 三、案例分析實(shí)現(xiàn):創(chuàng)建了一個(gè)十萬(wàn)個(gè)節(jié)點(diǎn)的長(zhǎng)列表,當(dāng)節(jié)點(diǎn)滾入到視窗中時(shí),背景就會(huì)從紅色變?yōu)辄S色
<div class="container"></div>
.container { display: flex; flex-wrap: wrap; } .target { margin: 5px; width: 20px; height: 20px; background: red; } 往 const $container = $(".container"); // 插入 100000 個(gè) <div class="target"></div> function createTargets() { const htmlString = new Array(100000) .fill('<div class="target"></div>') .join(""); $container.html(htmlString); } 這里,首先使用 function isInViewPort(element) { const viewWidth = window.innerWidth || document.documentElement.clientWidth; const viewHeight = window.innerHeight || document.documentElement.clientHeight; const { top, right, bottom, left } = element.getBoundingClientRect(); return top >= 0 && left >= 0 && right <= viewWidth && bottom <= viewHeight; } 然后開(kāi)始監(jiān)聽(tīng) $(window).on("scroll", () => { console.log("scroll !"); $targets.each((index, element) => { if (isInViewPort(element)) { $(element).css("background-color", "yellow"); } }); }); 通過(guò)上述方式,可以看到可視區(qū)域顏色會(huì)變成黃色了,但是可以明顯看到有卡頓的現(xiàn)象,原因在于我們綁定了 下面通過(guò) 首先創(chuàng)建一個(gè)觀察者 const observer = new IntersectionObserver(getYellow, { threshold: 1.0 });
function getYellow(entries, observer) { entries.forEach(entry => { $(entry.target).css("background-color", "yellow"); }); } 最后傳入觀察者,即 $targets.each((index, element) => { observer.observe(element); }); 可以看到功能同樣完成,并且頁(yè)面不會(huì)出現(xiàn)卡頓的情況 轉(zhuǎn)自https://www.cnblogs.com/smileZAZ/p/18216096 該文章在 2025/10/14 15:21:57 編輯過(guò) |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |