JavaScript - 控制滾動(dòng)條操作

今天玩 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 公用了 bodyscroll,解決思路就是讓兩個(gè) ListView 視同自己的 scroll 事件,同時(shí)設(shè)置 bodyoverflow: hidden

反思了下對(duì) cssjshtml 的滾動(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)圖表
    • 講解了 DOMMouseScrollonmousewheel的差異
    • 兼容的滾輪事件方法
    • 簡單的實(shí)例
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評(píng)論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,656評(píng)論 3 419
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評(píng)論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評(píng)論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,855評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,254評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評(píng)論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,473評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,014評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,833評(píng)論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,016評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,273評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評(píng)論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,730評(píng)論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,006評(píng)論 2 374

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

  • Window和document對(duì)象的區(qū)別 window對(duì)象window對(duì)象表示瀏覽器中打開的窗口window對(duì)象是...
    FConfidence閱讀 2,223評(píng)論 0 5
  • 一.首先介紹常用的屬性: HTML精確定位:scrollLeft,scrollWidth,clientWidth,...
    silingling閱讀 3,081評(píng)論 0 1
  • 一、JS前言 (1)認(rèn)識(shí)JS 也許你已經(jīng)了解HTML標(biāo)記(也稱為結(jié)構(gòu)),知道了CSS樣式(也稱為表示),會(huì)使用HT...
    凜0_0閱讀 2,788評(píng)論 0 8
  • 網(wǎng)頁可見區(qū)域?qū)挘篸ocument.body.clientWidth網(wǎng)頁可見區(qū)域高:document.body.cl...
    LuckyS007閱讀 665評(píng)論 0 0
  • 是的,很難 不知道你有沒有這樣的體驗(yàn) 上學(xué)的時(shí)候,當(dāng)你發(fā)現(xiàn)老師錯(cuò)了,并指出來的時(shí)候,她多半不會(huì)承認(rèn),可能還會(huì)惱羞成...
    還要個(gè)什么名字不成閱讀 322評(píng)論 0 0