ホームページ > 記事 > ウェブフロントエンド > JavaScript カスタム スクロール バーの実装コード
仕事上、一定の範囲を超えた内容に遭遇することがよくありますが、超えた内容をスクロールして表示するためにスクロールバーが使用されます。
しかし、ブラウザのデフォルトのスクロールバーを使用することはプロダクトマネージャーに軽蔑されがちですが、スクロールバーのスタイルはCSSを使用して変更することはできません、幸いなことにユニバーサルjsがあります^_^~~
さまざまなものがあります。プラグインはインターネット上にありますが、一番便利なのは自分で書くことです。遊びながら勉強することもできますし、食べ物や衣服も自分で作ることができます。
1. スクロールバーの高さ
2、上下ボタンをクリックするたびにスクロールバーはどのくらい移動する必要がありますか
3. 1pxのスクロールバーをドラッグするたびにページはどのくらい移動する必要がありますか?
全体のフレームワークはおそらく次のようになります:
まず最初の質問を見てみましょう。
コンテンツ領域の高さ、コンテンツの視覚的な高さ、スクロールバーのスクロール可能領域の高さはすでにわかっているため、コンテンツ領域とスクロールバーの間の距離はそれぞれの動きに比例するため、最初の問題は簡単に解決できます:
スクロールバーの可動範囲/スクロールバーの高さ=コンテンツの高さ/コンテンツの表示高さ
ボタンをクリックするたびにスクロールバーはどこまで移動する必要がありますか?
ここでは、ボタンがクリックされるたびにコンテンツ領域をどこまでスクロールするかを決定するパラメータ距離の値を設定します。この値を変更すると、コンテンツ領域のスクロール速度を変更できます。より良い処理方法と提案があれば、教えてください~
現在、残りはコンテンツ領域の各スクロールの距離を計算することです。スクロールバーはどこまで移動しますか?
スクロールバーの移動範囲 / 時間当たりのスクロールバーの移動距離 = コンテンツ領域の高さ / コンテンツ領域の時間当たりの移動距離
効果は次のとおりです:
ここで別の問題があります。つまり、区別する必要があります。 1回クリックまたは長押しと同時に。
そのため、ボタンを押してから離すまでの時間を判断する必要があります。現在、シングルクリックの場合は
スクロールバーをドラッグするたびに、スクロールバーは 1px 移動しますが、コンテンツ領域はどのくらい移動する必要がありますか?
まず、各 1PX 距離がスクロールバーの可動範囲の何パーセントに相当するかを把握し、コンテンツ領域の高さを得られたパーセンテージで割ることで、スクロールバーの 1px 移動ごとのコンテンツ領域の相対スクロール距離を求めます。
コンテンツエリアのスクロール距離 = コンテンツエリアの高さ / (スクロールバーのスクロールエリア / 1)
デモの完全なコードは次のとおりです:
注: 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シミュレーションスクロールバーの実装コードです。するだろうすべての人に役立つようにする 学ぶことは役に立ちます。
JavaScript カスタム スクロール バー実装コードに関連するその他の記事については、PHP 中国語 Web サイトに注目してください。