javascript自訂捲軸實現代碼,javascript捲軸
在工作中經常會遇到內容會超出固定的一個範圍,超出的內容一般會使用到捲軸來滾動顯示。
但是用瀏覽器預設的捲軸經常被產品經理鄙視,可是用css卻改變不了捲軸的樣式,還好,有萬能的js ^_^~~
網上有各種各樣的外掛程式,但最順手的還是自己寫的,還可以一邊擼一邊當學習,自己動手豐衣足食 (*^__^*)
其中這三個問題深深地困擾我:
- 1、捲軸高度
- 2、每次點擊向上、向下按鈕的時候捲軸應該移動多少距離
- 3、每拖動1px捲軸,頁面需要移動多少?
整個的架構大概是長這樣的:
先來看看第一個問題。
由於目前已經知道內容地區的高度和內容可視高度以及捲軸可捲動區域的高度了,由於內容地區與捲軸每次移動的距離都是成正比的,所以第一個問題很好解決:
捲軸可移動範圍 / 捲軸高度 = 內容高度 / 內容可視高度
每次點擊按鈕的時候捲軸應該移動多少距離?
這裡我是給參數distance設定一個值來決定每次點按鈕的時候,內容地區應該滾動多少的距離。改變這個值可以改變內容地區滾動的快慢,如果有更好的處理方法和建議記得告訴我喔~
目前,內容地區每次滾動的距離是知道了,剩下的是計算捲軸相對於應該移動多少距離?
捲軸可移動範圍 /捲軸每次移動距離 = 內容地區高度 / 內容地區每次移動多少距離
效果如下:
這裡還有一個問題,就是同時還得區分是單次點擊還是長按。
所以得判斷一下從按下按鈕到鬆開時候的時間長度,目前設定為<100ms為單次點擊,否則為長按:
拖動捲軸的時候,每移動1px捲軸,內容地區需要移動多少?
Crowdsourced Security Testing道每1PX的距離占捲軸可移動範圍的百分之幾,再用內容地區高度除以所得的這個百分比,就得出捲軸每移動1px內容地區相對滾動多少距離了。
內容地區滾動的距離 = 內容地區高度 / (捲軸捲動區域 / 1)
demo完整代碼如下:
注意:因為用的是seajs寫的,所以稍微留意下檔案的載入情況啦
css:
.wapper{scrollbar-3dlight-color:#000; position:relative; height:302px;width:300px;overflow:hidden;margin:0 auto;line-height:40px;text-align:center;} .area{background-color:#E2E2EF;width:100%; position:absolute;top:0px;left:0px;} .bar{position:absolute;top:0px;right:0px; height:100%;width:1rem;background-color:#ccc;} .scroll,.middle,.forward,.backward{display:block;cursor:pointer;position:absolute;right:0px;width:100%;} .forward,.backward{height:16px;background-color:#6868B1;} .middle{background-color:rgba(255, 255, 255, 0.22);top:16px;cursor:auto;} .scroll{position:absolute;top:0px;background-color:#C2C2E9;} .forward{top:0px;} .backward{bottom:0px;}
html:
<div class="wapper"> <div class="area"> <p>1、this is content</p> <p>2、this is content</p> <p>3、this is content</p> <p>4、this is content</p> <p>5、this is content</p> <p>6、this is content</p> <p>7、this is content</p> <p>8、this is content</p> <p>9、this is content</p> <p>10、this is content</p> <p>11、this is content</p> </div> <div class="bar"> <span class="forward"></span> <span class="middle"><em class="scroll"></em></span> <span class="backward"></span> </div></div><script type="text/javascript" src="../../lib/seajs/sea.js"></script><script type="text/javascript" src="../../lib/base/1.0.x/base.js"></script><script type="text/javascript">seajs.use(['lib/jquery/1.11.x/index.js', '_example/simulationScroll/simulationScroll.js'], function($, scroll) { scroll.init({ wapper: $('.wapper'), distance: 10, });});
js:
define(function(require, exports, module) { 'use strict'; var $ = require('lib/jquery/1.11.x/index.js'); var parameter = null; //檢測裝置類型 var startWhen, endWhen, moveWhen; var u = navigator.userAgent; if ( u.match(/\b(Windows\sNT|Macintosh)\b/) ) { // 滑鼠 startWhen = 'mousedown'; endWhen = 'mouseup'; moveWhen = 'mousemove'; } else { // 觸控螢幕 startWhen = 'touchstart'; endWhen = 'touchend'; moveWhen = 'touchmove'; } var simulation = { _mousedownTimer: 0, _setintervalId: 0, _longClick: false, //是否長點擊 _turnOf: null, //滾動方向 init: function(options) { var t = this; t._scroll = $('.scroll'); //捲軸 t._wapper = options.wapper.find('.area'); //內容地區 t._distance = options.distance; //點擊上下按鈕頁面每次滾動的距離 var forward = $('.forward'), middle = $('.middle'), backward = $('.backward'); parameter = { view: t._wapper.parent().innerHeight(), //視圖高度 page: t._wapper.height(), //內容高度 barArea: 0, //捲軸可移動範圍 scrollHeight: 0, //捲軸的高度 scrollDistance: 0 //捲軸每次滾動的距離 }; //初始化捲軸 if (parameter.page > parameter.view) { //捲軸可移動範圍 middle.height( parameter.view - forward.height() * 2); parameter.barArea = middle.height(); //捲軸高度 = 捲軸可滾動範圍 / (頁面高度 / 可視高度)的百分比 parameter.scrollHeight = parameter.barArea / (parameter.page / parameter.view) ; t._scroll.height(parameter.scrollHeight); //捲軸每次滾動的距離 = 捲軸可移動範圍 * 頁面每次滾動的百分比 parameter.scrollDistance = parameter.barArea / (parameter.page / t._distance) ; //拖動捲軸 t.liveEvent(); //點擊向前按鈕,如果按下滑鼠到鬆開滑鼠的時間長度<100ms,則為單次點擊 forward.bind(startWhen, function(e){ t._turnOf = 'forward'; t.longPress(e, t.direction ); }).bind(endWhen, function(e) { t.mouseupFun(e, t.direction); t._turnOf = null; }); //點擊向後按鈕 backward.bind(startWhen, function(e){ t.longPress(e, t.direction ); }).bind(endWhen, function(e){ t.mouseupFun(e, t.direction ); }); //註冊滑鼠滾動事件 // FF if(document.addEventListener){ document.addEventListener('DOMMouseScroll',t.mouseRuning,false); } //其它瀏覽器 document.onmousewheel = t.mouseRuning; } }, //滑鼠滾動 mouseRuning: function(e) { var t = simulation; e = e || window.event; //ie、FF if (e.detail) { if (e.detail < 0) { t._turnOf = 'forward'; t.direction (); } else{ t._turnOf = null; t.direction (); } // chrome } else if(e.wheelDelta) { if (e.wheelDelta > 0) { t._turnOf = 'forward'; t.direction (); } else{ t._turnOf = null; t.direction (); } } }, //判斷是否長點擊 longPress: function(e, moveFun ) { var t = this; if ( u.match(/\b(Windows\sNT|Macintosh)\b/) ) { e = e || window.event; // 限制為滑鼠左鍵點擊才觸發 if (/^mouse/.test(e.type) && e.which !== 1) { return; } } t._setintervalId = setInterval(function(){ t._mousedownTimer += 10; if( t._mousedownTimer >= 100 ){ moveFun(); } },20); }, mouseupFun: function(e, moveFun) { var t = this; if ( u.match(/\b(Windows\sNT|Macintosh)\b/) ) { e = e || window.event; // 限制為滑鼠左鍵點擊才觸發 if (/^mouse/.test(e.type) && e.which !== 1) { return; } } clearTimeout(t._setintervalId); if( t._mousedownTimer < 100 ) { moveFun(); } t._mousedownTimer = 0; }, direction:function() { var t = simulation, barTop = t._scroll.position().top, pageTop = t._wapper.position().top, moveDistance = {}; if ( t._turnOf === 'forward') { //頁面到頂,不執行任何操作 if (barTop == 0) { return; } moveDistance = { page: pageTop + t._distance, bar: barTop - parameter.scrollDistance } //如果捲軸距離頂部的距離少 < 每次滾動的距離,或者已經滾動到頂部,則不再滾動 if(barTop < parameter.scrollDistance || barTop <= 0){ moveDistance = { page: 0, bar: 0 } } } else { //頁面到底,不執行任何操作 if (barTop == parameter.barArea - parameter.scrollHeight){ return; } moveDistance = { page: pageTop - t._distance, bar: barTop + parameter.scrollDistance }; // 如果捲軸距離底部的距離值 < 每次滾動的距離 或者已經到底部,則一次滾到底 if ( moveDistance.bar + parameter.scrollHeight >= parameter.barArea) { moveDistance = { page: parameter.view - parameter.page, bar: parameter.barArea - parameter.scrollHeight }; } } t._scroll.css({top: moveDistance.bar}); t._wapper.css({top: moveDistance.page}); }, //拖動捲軸 liveEvent: function() { var t = this, draging = false, currentY = 0, lastY = 0, pageY = 0; //檢測裝置類型 var _ua = function(e) { var Pos = null; if ( u.match(/\b(Windows\sNT|Macintosh)\b/) ) { e = e || window.event; // 限制為滑鼠左鍵點擊才觸發 if (/^mouse/.test(e.type) && e.which !== 1) { return; } Pos = { left : e.pageX, top: e.pageY } } else { Pos = { left : e.originalEvent.targetTouches[0].pageX, top: e.originalEvent.targetTouches[0].pageY } } return Pos; }; var _start = function(e) { //監控滑鼠 e.preventDefault(); if (t._scroll.get(0).setCapture) { t._scroll.get(0).setCapture(); } draging = true; //記錄當前捲軸的座標 lastY = t._scroll.position().top; //記錄按下滑鼠的座標 pageY = _ua(e).top; }; var _drag = function(e) { if( draging ) { var pageTop = t._wapper.position().top; var barTop = t._scroll.position().top; //捲軸每移動1px,頁面相對滾動Npx 再 * 當前捲軸的到頂部的距離 var pageMoveDistance = -(parameter.page / (parameter.barArea / 1)) * barTop; if (lastY + ( _ua(e).top - pageY ) < 0) { currentY = 0; pageMoveDistance = 0; } else if( lastY + ( _ua(e).top - pageY) + parameter.scrollHeight >= parameter.barArea) { currentY = parameter.barArea - parameter.scrollHeight; pageMoveDistance = parameter.view - parameter.page; } else { currentY = lastY + ( _ua(e).top - pageY); } t._scroll.css({ top:currentY}); t._wapper.css({top: pageMoveDistance}); } }; var _end = function(e) { if (draging) { draging = false; //在IE下釋放對滑鼠的控制 if (t._scroll.get(0).setCapture) { t._scroll.get(0).releaseCapture(); } document.onmousemove = null; document.onmouseup = null; } }; t._scroll.bind( startWhen, _start ); t._wapper.bind( startWhen, _start ); $(document).bind( moveWhen, _drag ); $(document).bind( endWhen, _end ); $(document).bind('blur', _end); } } return simulation;});
以上就是javascript類比捲軸實現代碼,希望對大家的學習有所協助。
您可能感興趣的文章:
- js類比捲軸(橫向豎向)
- 判斷捲軸到底部的JS代碼
- jquery捲軸外掛程式jScrollPane的使用介紹
- JS和JQUERY擷取頁面大小,捲軸位置,元素位置(範例程式碼)
- js監聽捲軸滾動事件使得某個標籤內容始終位於同一位置
- 當捲軸滾動到頁面底部自動載入增加內容的js代碼
- js判斷捲軸是否已到頁面最底部或頂部執行個體
- JS實現判斷捲軸滾到頁面底部並執行事件的方法
- JS JQUERY實現捲軸自動滾到底的方法
- js操作捲軸事件執行個體