W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
?scroll
? 事件允許對(duì)頁面或元素滾動(dòng)作出反應(yīng)。我們可以在這里做一些有用的事情。
例如:
這是一個(gè)顯示當(dāng)前滾動(dòng)的小函數(shù):
window.addEventListener('scroll', function() {
document.getElementById('showScroll').innerHTML = window.pageYOffset + 'px';
});
在運(yùn)行中:
Current scroll = scroll the window
scroll
事件在 window
和可滾動(dòng)元素上都可以運(yùn)行。
我們?nèi)绾问鼓承〇|西變成不可滾動(dòng)?
我們不能通過在 onscroll
監(jiān)聽器中使用 event.preventDefault()
來阻止?jié)L動(dòng),因?yàn)樗鼤?huì)在滾動(dòng)發(fā)生 之后 才觸發(fā)。
但是我們可以在導(dǎo)致滾動(dòng)的事件上,例如在 pageUp 和 pageDown 的 keydown
事件上,使用 event.preventDefault()
來阻止?jié)L動(dòng)。
如果我們向這些事件中添加事件處理程序,并向其中添加 event.preventDefault()
,那么滾動(dòng)就不會(huì)開始。
啟動(dòng)滾動(dòng)的方式有很多,使用 CSS 的 overflow
屬性更加可靠。
有幾個(gè)練習(xí)題,你可以解決或者瀏覽以下幾個(gè)任務(wù)來看一下 onscroll
的應(yīng)用。
創(chuàng)建一個(gè)無限的頁面。當(dāng)訪問者滾動(dòng)到頁面末端時(shí),它會(huì)自動(dòng)將當(dāng)期日期時(shí)間附加到文本中(以便訪問者可以滾動(dòng)更多內(nèi)容)。
請(qǐng)注意滾動(dòng)的兩個(gè)重要特性:
因此,“滾動(dòng)到末端”應(yīng)該意味著訪問者離文檔末端的距離不超過 100px。
P.S. 在現(xiàn)實(shí)生活中,我們可能希望顯示“更多信息”或“更多商品”。
解決方案的核心是一個(gè)函數(shù),當(dāng)我們?cè)陧撁婺┒藭r(shí),該函數(shù)可以向頁面添加更多日期(或者在實(shí)際開發(fā)中是加載更多內(nèi)容)。
我們可以立即調(diào)用它,并將其添加為 window.onscroll
處理程序。
最重要的問題是:“如何檢測(cè)頁面滾動(dòng)到了末端?”
讓我們使用相對(duì)于窗口的坐標(biāo)。
文檔(document)在 <html>
標(biāo)簽中被表示(被包含)為 document.documentElement
。
我們可以通過 document.documentElement.getBoundingClientRect()
來獲取整個(gè)文檔相對(duì)于窗口的坐標(biāo)。bottom
屬性將是文檔末端的相對(duì)于窗口的坐標(biāo)。
例如,如果整個(gè) HTML 文檔的高度是 2000px
,那么:
// 當(dāng)我們?cè)陧撁骓敹藭r(shí)
// 相對(duì)于窗口 top = 0
document.documentElement.getBoundingClientRect().top = 0
// 相對(duì)于窗口 bottom = 2000
// 如果文檔太長(zhǎng),那么可能會(huì)遠(yuǎn)遠(yuǎn)超出窗口底部
document.documentElement.getBoundingClientRect().bottom = 2000
如果我們向下滾動(dòng) 500px
,那么:
// 文檔頂端在窗口之方 500px
document.documentElement.getBoundingClientRect().top = -500
// 文檔末端相對(duì)于窗口近了 500px
document.documentElement.getBoundingClientRect().bottom = 1500
當(dāng)我們滾動(dòng)到文檔末端時(shí),假設(shè)窗口高度為 600px
:
// 文檔頂端在窗口上方 -1400px
document.documentElement.getBoundingClientRect().top = -1400
// 文檔末端相對(duì)于窗口坐標(biāo)為 600px
document.documentElement.getBoundingClientRect().bottom = 600
請(qǐng)注意,bottom
不能為 0
,因?yàn)樗肋h(yuǎn)不會(huì)到達(dá)窗口頂部。bottom
坐標(biāo)的最低限度是窗口高度(我們假設(shè)其為 600
),我們無法再向上滾動(dòng)了。
我們可以獲得窗口的高度為 document.documentElement.clientHeight
。
對(duì)于本任務(wù),我們需要知道何時(shí)文檔末端距窗口底部不超過 100px
(即,如果窗口高度為 600px
,則為 600-700px
)。
所以,函數(shù)如下:
function populate() {
while(true) {
// 文檔末端
let windowRelativeBottom = document.documentElement.getBoundingClientRect().bottom;
// 如果用戶將頁面滾動(dòng)的距離不夠遠(yuǎn)(文檔末端距窗口底部 >100px)
if (windowRelativeBottom > document.documentElement.clientHeight + 100) break;
// 讓我們添加更多數(shù)據(jù)
document.body.insertAdjacentHTML("beforeend", `<p>Date: ${new Date()}</p>`);
}
}
創(chuàng)建一個(gè)“到頂部”按鈕來幫助頁面滾動(dòng)。
它應(yīng)該像這樣運(yùn)行:
假設(shè)我們有一個(gè)速度較慢的客戶端,并且希望節(jié)省它們?cè)谝苿?dòng)端的流量。
為此,我們決定不立即顯示圖像,而是將其替換為占位符,如下所示:
<img src="placeholder.svg" width="128" height="128" data-src="real.jpg">
因此,最初所有圖像均為 placeholder.svg
。當(dāng)頁面滾動(dòng)到用戶可以看到圖像位置時(shí) —— 我們就會(huì)將 src
更改為 data-src
的 src
,從而加載圖像。
滾動(dòng)它可以看到圖像是“按需”加載的。
要求:
data-src
?。代碼不應(yīng)該改動(dòng)它們。P.S. 如果你有能力,可以創(chuàng)建一個(gè)更高級(jí)的解決方案,以“預(yù)加載”當(dāng)前位置下方/之后一頁的圖像。
P.P.S. 僅處理垂直滾動(dòng),不處理水平滾動(dòng)。
onscroll
處理程序應(yīng)該檢查哪些圖像是可見的,并顯示它們。
我們還希望在頁面加載時(shí)運(yùn)行它,以檢測(cè)即將可見的圖像并加載它們。
該代碼應(yīng)該在文檔加載完成時(shí)執(zhí)行,以便可以訪問文檔內(nèi)容。
或者將該代碼放在 <body>
底部:
// ...頁面內(nèi)容在上面...
function isVisible(elem) {
let coords = elem.getBoundingClientRect();
let windowHeight = document.documentElement.clientHeight;
// 頂部元素邊緣可見嗎?
let topVisible = coords.top > 0 && coords.top < windowHeight;
// 底部元素邊緣可見嗎?
let bottomVisible = coords.bottom < windowHeight && coords.bottom > 0;
return topVisible || bottomVisible;
}
showVisible()
函數(shù)使用通過 isVisible()
實(shí)現(xiàn)的可見性檢查,來加載可見圖像:
function showVisible() {
for (let img of document.querySelectorAll('img')) {
let realSrc = img.dataset.src;
if (!realSrc) continue;
if (isVisible(img)) {
img.src = realSrc;
img.dataset.src = '';
}
}
}
showVisible();
window.onscroll = showVisible;
P.S. 此解決方案還有一個(gè) isVisible
的變體,可以“預(yù)加載”當(dāng)前文檔滾動(dòng)上方/下方 1 頁內(nèi)的圖像
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: