故問(wèn)題拆分成兩個(gè):
- 如何判斷圖片出現(xiàn)在了當(dāng)前視口 (即如何判斷我們能夠看到圖片)
- 如何控制圖片的加載
如何判斷圖片出現(xiàn)在了當(dāng)前視口
clientTop
,offsetTop
,clientHeight
以及scrollTop
各種關(guān)于圖片的高度作比對(duì)
這些高度都代表了什么意思?
HTML精確定位:scrollLeft
,scrollWidth
,clientWidth
,offsetWidth
-
scrollHeight
: 獲取對(duì)象的滾動(dòng)高度。 -
scrollLeft
:設(shè)置或獲取位于對(duì)象左邊界和窗口中目前可見(jiàn)內(nèi)容的最左端之間的距離 -
scrollTop
:設(shè)置或獲取位于對(duì)象最頂端和窗口中可見(jiàn)內(nèi)容的最頂端之間的距離 -
scrollWidth
:獲取對(duì)象的滾動(dòng)寬度 -
offsetHeight
:獲取對(duì)象相對(duì)于版面或由父坐標(biāo)offsetParent
屬性指定的父坐標(biāo)的高度 -
offsetLeft
:獲取對(duì)象相對(duì)于版面或由offsetParent
屬性指定的父坐標(biāo)的計(jì)算左側(cè)位置 -
offsetTop
:獲取對(duì)象相對(duì)于版面或由offsetTop
屬性指定的父坐標(biāo)的計(jì)算頂端位置 -
event.clientX
相對(duì)文檔的水平座標(biāo) -
event.clientY
相對(duì)文檔的垂直座標(biāo) -
event.offsetX
相對(duì)容器的水平坐標(biāo) -
event.offsetY
相對(duì)容器的垂直坐標(biāo) -
document.documentElement.scrollTop
垂直方向滾動(dòng)的值 -
event.clientX+document.documentElement.scrollTop
相對(duì)文檔的水平座標(biāo)+垂直方向滾動(dòng)的量
這里是javascript中建造遷移轉(zhuǎn)變代碼的常用屬性
- 網(wǎng)頁(yè)可見(jiàn)區(qū)域?qū)挘?
document.body.clientWidth
; - 網(wǎng)頁(yè)可見(jiàn)區(qū)域高:
document.body.clientHeight
; - 網(wǎng)頁(yè)可見(jiàn)區(qū)域?qū)挘?
document.body.offsetWidth
(包含邊線的寬); - 網(wǎng)頁(yè)可見(jiàn)區(qū)域高:
document.body.offsetHeight
(包含邊線的寬); - 網(wǎng)頁(yè)正文全文寬:
document.body.scrollWidth
; - 網(wǎng)頁(yè)正文全文高:
document.body.scrollHeight
; - 網(wǎng)頁(yè)被卷去的高:
document.body.scrollTop
; - 網(wǎng)頁(yè)被卷去的左:
document.body.scrollLeft
; - 網(wǎng)頁(yè)正文項(xiàng)目組上:
window.screenTop
; - 網(wǎng)頁(yè)正文項(xiàng)目組左:
window.screenLeft
; - 屏幕辨別率的高:
window.screen.height
; - 屏幕辨別率的寬:
window.screen.width
; - 屏幕可用工作區(qū)高度:
window.screen.availHeight
;
僅僅知道它靜態(tài)的高度還不夠,我們還需要知道動(dòng)態(tài)的
如何動(dòng)態(tài)?監(jiān)聽(tīng)window.scroll
事件
如何控制圖片的加載
<img data-src="JimiLee.jpg">
首先設(shè)置一個(gè)臨時(shí)屬性 data-src
,控制加載時(shí)使用 src
代替 data-src
改進(jìn)下,如何判斷圖片出現(xiàn)在了當(dāng)前視口
引入一個(gè)新的 API, Element.getBoundingClientRect()
方法返回元素的大小及其相對(duì)于視口的位置。
https://mdn.mozillademos.org/files/15087/rect.png
那如何判斷圖片出現(xiàn)在了當(dāng)前視口呢,根據(jù)示例圖示意,代碼如下,這個(gè)就比較好理解了,就可以很容易地背會(huì)
// clientHeight 代表當(dāng)前視口的高度
img.getBoundingClientRect().top < document.documentElement.clientHeight
監(jiān)聽(tīng) window.scroll
事件也優(yōu)化一下
加個(gè)節(jié)流器,提高性能。工作中一般使用 lodash.throttle
就可以了
_.throttle(func, [wait=0], [options={}])
如何判斷圖片出現(xiàn)在了當(dāng)前視口
方案二使用的方法是: window.scroll
監(jiān)聽(tīng) Element.getBoundingClientRect()
并使用 _.throttle
節(jié)流
一系列組合動(dòng)作太復(fù)雜了,于是瀏覽器出了一個(gè)三合一事件: IntersectionObserver
API,一個(gè)能夠監(jiān)聽(tīng)元素是否到了當(dāng)前視口的事件,一步到位!
事件回調(diào)的參數(shù)是IntersectionObserverEntry
的集合,代表關(guān)于是否在可見(jiàn)視口的一系列值
其中,entry.isIntersecting
代表目標(biāo)元素可見(jiàn)
const observer = new IntersectionObserver((changes) => {
// changes: 目標(biāo)元素集合
changes.forEach((change) => {
// intersectionRatio
if (change.isIntersecting) {
const img = change.target
img.src = img.dataset.src
observer.unobserve(img)
}
})
})
observer.observe(img)
當(dāng)然,IntersectionObserver
除了給圖片做懶加載外,還可以對(duì)單頁(yè)應(yīng)用資源做預(yù)加載。
總結(jié)一下
-
window.scroll
監(jiān)聽(tīng)各種top
與height
并使用_.throttle
節(jié)流,但是不好理解各種top
與hegith
-
window.scroll
監(jiān)聽(tīng)getBoundingClientRect
并使用_.throttle
節(jié)流,沒(méi)有一個(gè)統(tǒng)一事件,相對(duì)復(fù)雜 -
IntersectionObserver
,瀏覽器推出了一個(gè)事件,方便簡(jiǎn)單 -
img.loading=lazy
,瀏覽器直接給你解決,開(kāi)發(fā)者直接標(biāo)注屬性