1. 程式人生 > >重寫移動端滾動條[iScroll.js核心程式碼]

重寫移動端滾動條[iScroll.js核心程式碼]

最近寫元件庫的時後,發現這個滾動條是真的醜啊,決定重新擼一個滾動條:

首先咱們回顧一下移動端瀏覽器滾動條特性:

  • 滾動條在開始滾動時漸顯,滾動結束後漸隱
  • 滾動條不佔內容區寬度,懸浮固定
  • 滾動條高度(深灰)和滾動區可視高度(淺灰)比等於滾動區可視高度和滾動目標的高度
  • 當滾動目標的高度小於滾動區可視高度的時候,滾動條不顯示,並且無法滾動
  • 只有在滾動滾動目標時,才能觸發滾動
  • 當滾動條頂部觸頂和底部觸底的時候,不能繼續滾動
  • 只有在滾動大於一個固定值時,才被視為滾動開始
  • 根據滾動的差值,計算是向上滾動還是向下滾動
  • 滾動條是動態生成的

好啦,接下來咱們開始一步一步實現,需要哪些知識點:

  • 漸隱漸顯

opacity: 1; transition: opacity 500ms ease-in-out;

opacity: 0; transition: opacity 500ms ease-in-out;
複製程式碼
  • 懸浮固定

position 定位
滾動條寬度width為3px;
複製程式碼
  • 宣告變數

var conHeight = contentBox.offsetHeight;        //滾動目標的整體高度
var _width = mainBox.clientWidth;               //滾動可視區的寬度
var _height = mainBox.clientHeight;             //滾動可視區的高度
var _scrollWidth = element.offsetWidth;         //滾動條的寬度
var _left = _width - _scrollWidth;              //定位滾動條應該距離左邊寬度
複製程式碼

看到這裡是不是有種一目瞭然的感覺,所以滾動條的寬度就是:
var _scrollHeight = parseInt(_height * (_height / conHeight))

  • 當滾動目標的高度小於滾動區可視高度的時候,滾動條不顯示,反之則顯示,不過透明度為0,哈哈,是不是很賤...

切記不顯示和透明度為0還是不一樣的


if (_scrollHeight >= mainBox.clientHeight) {
    element.parentNode.style.display = "none";
} else {
    element.parentNode.style.opacity = "0"; //有滾動條的話先將透明度設定為0
}
複製程式碼
  • 只有在滾動滾動目標時,才能觸發滾動

//如果滾動的不是目標元素,此處只有觸控的是a時才能滾動,否則直接return;
if (event.changedTouches[0].target.tagName !== 'A') return false;
複製程式碼
  • 當滾動條頂部觸頂和底部觸底的時候,不能繼續滾動

if (elT === '0rem' && this.direction == '1') console.log('到頂了不要再向上滑了');
if (elT === parseInt(elParentH) - parseInt(elH) + 'rem' && this.direction == '0') console.log('到底了不要再往下滑了');
複製程式碼
  • 只有在滾動大於一個固定值時,才被視為滾動開始

這裡我們暫且設定這個最小移動高度為 minRange = 10;

  • 根據滾動的差值,計算是向上滾動還是向下滾動,怎麼判斷滾動差值呢,好,clientY來了

  • 滾動條是動態生成的,這個好辦,直接粘程式碼:


var _scrollBox = doc.createElement('div');
var _scroll = doc.createElement('div');
_scrollBox.appendChild(_scroll);
_scroll.className = className;
mainBox.appendChild(_scrollBox);
複製程式碼

好了,接下來就是最關鍵的時候了,怎麼去把這些邏輯聯動起來呢,這時候HTML5觸控事件就粉墨登場了:touchstart touchmove touchend三劍客 具體怎麼使用,大家就自行百度了,下面附上我的專案程式碼:供各位大神閱覽: Github地址

有不懂或者有疑問,歡迎大家留言。