今天玩 antd-mobile
碰到一個(gè)滾動(dòng)條的問題:在 Tab
組件中使用多個(gè) ListView
,當(dāng)操作第一個(gè) Tab
中的 ListView A
組件,加載數(shù)據(jù),滾動(dòng),底部加載一切正常,可是當(dāng)我點(diǎn)擊切換到第二個(gè) Tab
中的 ListView B
組件時(shí),發(fā)現(xiàn)在 ListView B
組件中滾動(dòng)屏幕,觸發(fā)了 ListView A
組件中的滾動(dòng)事件,同樣的,在 ListView A
組件中滾動(dòng)屏幕,也會(huì)觸發(fā) ListView
組件的滾動(dòng)事件。
導(dǎo)致這個(gè)奇葩問題的原因居然是兩個(gè) ListView
公用了 body
的 scroll
,解決思路就是讓兩個(gè) ListView
視同自己的 scroll
事件,同時(shí)設(shè)置 body
的 overflow: hidden
。
反思了下對(duì) css
、js
、html
的滾動(dòng)相關(guān)操作的技能太淺,特別整理了這篇筆記。
Css 屬性 overflow
設(shè)置內(nèi)容溢出顯示狀態(tài)
div
{
width:150px;
height:150px;
overflow:scroll;
}
設(shè)置div內(nèi)容溢出時(shí)顯示滾動(dòng)條
可能的值
值 | 描述 |
---|---|
visible | 默認(rèn)值。內(nèi)容不會(huì)被修剪,會(huì)呈現(xiàn)在元素框之外。 |
hidden | 內(nèi)容會(huì)被修剪,并且其余內(nèi)容是不可見的。 |
scroll | 內(nèi)容會(huì)被修剪,但是瀏覽器會(huì)顯示滾動(dòng)條以便查看其余的內(nèi)容。 |
auto | 如果內(nèi)容被修剪,則瀏覽器會(huì)顯示滾動(dòng)條以便查看其余的內(nèi)容。 |
inherit | 規(guī)定應(yīng)該從父元素繼承 overflow 屬性的值。 |
Js 監(jiān)聽滾動(dòng)事件
window.addEventListener('scroll', this.handleScroll); // 添加滾動(dòng)事件
window.removeEventListener('scroll', this.handleScroll); // 刪除滾動(dòng)事件
handleScroll: function (e) {
console.log('瀏覽器滾動(dòng)事件')
}
Js 獲取與滾輪與頂部距離小技巧
各瀏覽器下 scrollTop的差異 IE6/7/8:
- 對(duì)于沒有doctype聲明的頁面里可以使用 document.body.scrollTop 來獲取 scrollTop高度 ;
- 對(duì)于有doctype聲明的頁面則可以使用 document.documentElement.scrollTop; Safari:
- safari 比較特別,有自己獲取scrollTop的函數(shù) : window.pageYOffset ; Firefox:
- 火狐等等相對(duì)標(biāo)準(zhǔn)些的瀏覽器就省心多了,直接用 document.documentElement.scrollTop ;
chrome
不認(rèn)識(shí) document.documentElement.scrollTop
如果有文檔聲明(即網(wǎng)頁第一句的docType)的情況下,標(biāo)準(zhǔn)瀏覽器是只認(rèn)識(shí) documentElement.scrollTop
的,但chrome雖然我感覺比firefox還標(biāo)準(zhǔn),但卻不認(rèn)識(shí)這個(gè),在有文檔聲明時(shí),chrome也只認(rèn)識(shí)document.body.scrollTop.
由于在不同情況下,document.body.scrollTop與document.documentElement.scrollTop都有可能取不到值
document.body.scrollTop與document.documentElement.scrollTop兩者有個(gè)特點(diǎn),就是同時(shí)只會(huì)有一個(gè)值生效。比如document.body.scrollTop能取到值的時(shí)候,document.documentElement.scrollTop就會(huì)始終為0;反之亦然。所以,如果要得到網(wǎng)頁的真正的scrollTop值
// 方法一
var scrollTop = document.body.scrollTop + document.documentElement.scrollTop;
var scrollLeft = document.body.scrollLeft + document.documentElement.scrollLeft;
// 方法二
var scrollLeft = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
var scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
// 方法三
var scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop || 0;
這樣就可以解決距離頂部的問題。
Js 判斷滾動(dòng)到底部
判斷滾動(dòng)條到底部,需要用到DOM的三個(gè)屬性值,即scrollTop、clientHeight、scrollHeight。
-
scrollTop
為滾動(dòng)條在Y軸上的滾動(dòng)距離。 -
clientHeight
為內(nèi)容可視區(qū)域的高度。 -
scrollHeight
為內(nèi)容可視區(qū)域的高度加上溢出(滾動(dòng))的距離。
從這個(gè)三個(gè)屬性的介紹就可以看出來,滾動(dòng)條到底部的條件即為scrollTop + clientHeight == scrollHeight
//滾動(dòng)條在Y軸上的滾動(dòng)距離
function getScrollTop(){
return scrollTop = document.body.scrollTop + document.documentElement.scrollTop;
}
//文檔的總高度
function getScrollHeight(){
return scrollHeight = document.body.scrollHeight + document.documentElement.scrollHeight;
}
//瀏覽器視口的高度
function getWindowHeight(){
return document.compatMode == "CSS1Compat" ? windowHeight = document.documentElement.clientHeight : windowHeight = document.body.clientHeight;
}
window.onscroll = function(){
if(getScrollTop() + getWindowHeight() == getScrollHeight()){
alert("you are in the bottom!");
}
};
帶動(dòng)笑的滾動(dòng)
使用 Jquery
實(shí)現(xiàn)
$('div').click(function(){$('html,body').animate({scrollTop:$('.a').offset().top}, 800);});
Js 滾動(dòng)相關(guān)API
- 網(wǎng)頁可見區(qū)域?qū)挘?document.body.clientWidth;
- 網(wǎng)頁可見區(qū)域高: document.body.clientHeight;
- 網(wǎng)頁可見區(qū)域?qū)挘?document.body.offsetWidth; (包括邊線的寬)
- 網(wǎng)頁可見區(qū)域高: document.body.offsetHeight; (包括邊線的寬)
- 網(wǎng)頁正文全文寬: document.body.scrollWidth;
- 網(wǎng)頁正文全文高: document.body.scrollHeight;
- 網(wǎng)頁被卷去的高: document.body.scrollTop; (當(dāng)前滾動(dòng)條距離頂部的距離)
- 網(wǎng)頁被卷去的左: document.body.scrollLeft;(當(dāng)前滾動(dòng)條距離左邊的距離)
- 網(wǎng)頁正文部分上: window.screenTop;
- 網(wǎng)頁正文部分左: window.screenLeft;
- 屏幕分辨率的高: window.screen.height;
- 屏幕分辨率的寬: window.screen.width;
- 屏幕可用工作區(qū)高度: window.screen.availHeight;
- 屏幕可用工作區(qū)寬度:window.screen.availWidth;
- scrollHeight: 獲取對(duì)象的滾動(dòng)高度。
- scrollLeft:設(shè)置或獲取位于對(duì)象左邊界和窗口中目前可見內(nèi)容的最左端之間的距離
- scrollTop:設(shè)置或獲取位于對(duì)象最頂端和窗口中可見內(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)的量
- 要獲取當(dāng)前頁面的滾動(dòng)條縱坐標(biāo)位置,用:
- document.documentElement.scrollTop;
- 而不是:
- document.body.scrollTop;
- documentElement 對(duì)應(yīng)的是 html 標(biāo)簽,而 body 對(duì)應(yīng)的是 body 標(biāo)簽
拓展
-
JS滾輪事件(mousewheel/DOMMouseScroll)了解
- 一張較全的IE7, IE10, Chrome, 以及FireFox,鼠標(biāo)向下滾動(dòng)圖表
- 講解了
DOMMouseScroll
、onmousewheel
的差異 - 兼容的滾輪事件方法
- 簡單的實(shí)例