JSアナログスクロールバー(demoとソースコードのダウンロードがあり、ローラークリックイベントをサポートする)

43396 ワード

游覧机が持参したスクロールバーは美観の面ではあまりきれいではないため、多くのデザイナーが自分で设计したスクロールバーを通じてこのような効果を望んでいる.JSシミュレーションスクロールバーは実はjQueryがこのようなプラグインやKISSYを持っているのを早く见て、自分がいつこの神秘的な东东を研究したいと思っていた.考えてみればdemoをしようとしたが、研究もできず、最初は2つの点が分からなかった.1つは、現在のスクロールバーの幅(水平スクロール)や高さ(垂直スクロール)はどのように計算するか分からない.二つ目は、水平スクロールの距離と垂直スクロールの距離は一度にどれだけスクロールしますか?どうやって計算するか分からない.だからずっと研究できなかった!最近この方面についてのブログを見てから、計算方法がだんだん分かってきました.
JSでスクロールバーをシミュレートするには、次の点を知る必要があります.
   1. スクロールバーの幅を動的に設定するscrollBarWidth=(コンテナの幅*コンテナの幅/内容の幅)
スクロールバーの高さを動的に設定するscrollBarHeight=(コンテナの高さ*コンテナの高さ/内容の高さ)
   2. 一度にどれだけの距離を移動するか:計算方法は次のとおりです.
xy=(コンテンツの幅-コンテナの幅)*移動距離/(コンテナの幅-スクロールバーの幅)または
xy=(コンテンツの高さ-コンテナの高さ)*移動距離/(コンテナの高さ-スクロールバーの高さ)
移動距離を設定できるデフォルトは100です
   3. マウスホイールイベント:上へスクロール(または左へスクロール)するか、下へスクロール(または右へスクロール)するかを判断する遊覧機の互換性.
       1. IE 6内を含むローラーイベントはonmousewheelで、firefoxは一人でDOMMouseScrollイベントを使用しています.遊覧機は上にスクロールするか下にスクロールするかを判断します.
              1. 火狐遊覧器はeventを下に通過すると判断した.detailという属性判断は-3なら下が3なら上を向く.
     2.他の遊覧機はeventを通ります.wheelDeltaは-120なら下を向いて120なら上を向いていると判断します
火狐遊覧器以外は以下の関数でテストできます.
       document.body.onmousewheel = function(event) { event = event || window.event; console.log(event.wheelDelta); };
火狐遊覧器は次の関数でテストできます.
      document.body.addEventListener("DOMMouseScroll", function(event) { console.log(event.detail); });
   4. ドラッグイベントについて:setCaptureというものを使っていますが、このものはいったいどういう意味ですか?これまでjsドラッグ事件にこんなものがあるとは知らなかった.Googleでは、マウスキャプチャ(setCapture)が現在のドキュメントの指定されたオブジェクトにマウスイベントをキャプチャする役割を果たしていることがわかりました.このオブジェクトは、現在のアプリケーションまたはシステム全体に対してすべてのマウスイベントを受信します.ただしsetCaptureではキーボードイベントはサポートされていません.onmousedown、onmouseup、onmousemove、onclick、ondblick、onmouseover、onmouseoutのマウスイベントのみがキャプチャされます.
この方法でリリースするJqueryのbindとunbindバインドイベントと同じです.
  5. まず、ローライベントの互換性に基づいて、次のコードを書くことができます.
/*

     *               

     *           event.delta         0              

     * win7               event.detail          -3             3       

     * win7         event.wheelDelta       -120          120      

     */

    _addEvent: function(){

        var EventProcess = function(event) {

            var type = event.type;

            if(type == 'DOMMouseScroll' || type == 'mousewheel') {

                 event.delta = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;

            }

            if (event.srcElement && !event.target) {

                event.target = event.srcElement;    

            }

            if (!event.preventDefault && event.returnValue !== undefined) {

                event.preventDefault = function() {

                    event.returnValue = false;

                };

            }

            return event;

        }

        if(window.addEventListener) {

            return function(el,type,fn,capture) {

                if (type === "mousewheel" && document.mozHidden !== undefined) {

                    type = "DOMMouseScroll";

                }

                el.addEventListener(type, function(event) {

                    fn.call(this, EventProcess(event));

                }, capture || false);

            }

        }else if (window.attachEvent) {

            return function(el, type, fn, capture) {

                el.attachEvent("on" + type, function(event) {

                    event = event || window.event;

                    fn.call(el, EventProcess(event));    

                });

            }

        }   

}

 
次に、上記の方法では、スクロールバーが下(または右)にスクロールされているか、上(または左)にスクロールされているかを判断するために呼び出すことができます.
var wheelEvent = self._addEvent();

wheelEvent(container,'mousewheel',function(event){

    var wheelDelta = event.delta;

    if(wheelDelta < 0){

    //    

    }else {

    //     

    }

});

次に、このJSシミュレーションスクロールバーコンポーネントについて説明します.
 1. 水平スクロールバーと垂直スクロールバーの構成をサポートします.
 2. サポートページには複数のスクロールバーがあり、一度初期化すればOKです.
 3. デフォルトのスクロールバーは、パラメータisHiddenScrollを使用してtrueにスクロールバーを非表示にすることもできます.マウスがその領域を移動したときにスクロールバーを表示します.
 4. デフォルトでは、次のパラメータを設定する必要があります.
containerCls:外層容器classクラス名
contentCls:コンテンツ領域classクラス名
wrapScrollBarCls:現在のスクロールバーコンテナclassクラス名
scrollBarCls:現在のスクロールバーclassクラス名
sMoveDis:マウスでホイールをクリックまたはスクロールした場合、スクロールバーが一度に移動する距離
isVertical:垂直スクロールバーかどうかデフォルトは横スクロールバーfalse
isHiddenScroll:デフォルトでスクロールバーを非表示にするかどうかマウスを上に移動してデフォルトでfalseを表示するかどうか
次の図のように、効果がどのような横スクロールバーであるかを見てみましょう.
 
一般スクロールバーは次のとおりです.
ページHTMLコードは以下の通りです.
<!--       -->

    <div class="container">        

        <div class="cont">                                                                                                                                                                                                                                                                                                                                </div>

        <div class="wrap-scroll-bar">

            <div class="scroll-bar"></div>

        </div>

    </div>

    <div class="container">        

        <div class="cont" style="width:1000px;">                                                                                                                                                                                                                                                                                                                                </div>

        <div class="wrap-scroll-bar">

            <div class="scroll-bar"></div>

        </div>

    </div> 

    <!--        -->

    <!-- <div class="container">        

        <div class="cont">                                                                                                                                                                                                                                                                                                                                </div>

        <div class="wrap-scroll-bar">

            <div class="scroll-bar"></div>

        </div>

    </div>-->

CSSコードは以下の通りです.
 <style>

    .container {

        position:relative;

        width:500px;

        height:200px;

        margin:50px auto 0;

        overflow: hidden;

     }

     .cont {

        background:#999;

        color: #fff;

        height:185px;

        position:absolute;

        top:0;

        left:0;

        width:2000px;

     }

     .wrap-scroll-bar {

        position:absolute;

        bottom:0;

        left:0;

        height:15px;

        background:#e6e6e6;

        width:100%;

        overflow:hidden;

     }

     .scroll-bar {

        position:absolute;

        bottom:0;

        height:15px;

        background:#ccc;

        left:0;

        width:20px;

     }



     /**      css

     .container {

        position:relative;

        width:500px;

        height:200px;

        margin:50px auto 0;

        overflow: hidden;

     }

     .cont {

        color: #fff;

        background:#999;

        width:485px;

        height:1000px;

        position:absolute;

        top:0;

        left:0;

     }

     .wrap-scroll-bar {

        position:absolute;

        right:0;

        top:0;

        width:15px;

        background:#e6e6e6;

        height:100%;

        overflow:hidden;

     }

     .scroll-bar {

        position:absolute;

        top:0;

        height:20px;

        background:#ccc;

        left:0;

        width:15px;

     } **/

     .hidden {display:none;}

JSコードは以下の通りである.
 
/**

 * JS     

 * @date 2013-12-06

 * @email 879083421

 */



 function SimulateScroll(options) {

     

     this.config = {

         containerCls                :  '.container',                    //     

         contentCls                  :  '.cont',                         //     

         wrapScrollBarCls            : '.wrap-scroll-bar',               //         

         scrollBarCls                :  '.scroll-bar',                   //      

         sMoveDis                    : 100,                              //

         isVertical                  : false,                            //                  

         isHiddenScroll              : false                              //                           



     };



     this.cache = {

        diX       :  0,

        diY       : 0

     };

     this.init(options);

 }

 

 SimulateScroll.prototype = {

    init: function(options) {



        this.config = $.extend(this.config,options || {});



        var self = this,

            _config = self.config,

            _cache = self.cache;



        /*

         *               

         *                         

         */

        if(!_config.isVertical) {

            

            $(_config.containerCls).each(function(index,item) {



                var containerWidth = $(item).width(),

                    contentWidth = $(_config.contentCls,item).width();



                //            (      *       /      )

                $(_config.scrollBarCls,item).width(containerWidth * containerWidth /contentWidth);

                var scrollBarWidth = $(_config.scrollBarCls,item).width();



                //        

                self._dragScroll();



                //        

                self._clickScroll();

                

                //       

                self._initMouseWheel(item);

            });

            

            

        }else {

            $(_config.containerCls).each(function(index,item) {

                var containerHeight = $(item).height(),

                    contentHeight = $(_config.contentCls,item).height();

                

                //            (      ×       /      )

                $(_config.scrollBarCls,item).height(containerHeight * containerHeight /contentHeight);

                var scrollBarHeight = $(_config.scrollBarCls,item).height();

                

                //        

                self._dragScroll();



                //        

                self._clickScroll();

                

                //       

                self._initMouseWheel(item);

            });

        }

        

        //        

        if(_config.isHiddenScroll) {

            $(_config.wrapScrollBarCls).each(function(index,item){

                !$(item).hasClass('hidden') && $(item).addClass('hidden');

            });

            $(_config.containerCls).each(function(index,item){

                $(item).hover(function(){

                    $(_config.wrapScrollBarCls,item).hasClass("hidden") && 

                    $(_config.wrapScrollBarCls,item).removeClass('hidden');

                },function(){

                    !$(_config.wrapScrollBarCls,item).hasClass("hidden") && 

                    $(_config.wrapScrollBarCls,item).addClass('hidden');

                })

            });

        }

    },

    

    /**

     *      

     */

    _dragScroll: function() {

        var self = this,

            _config = self.config,

            _cache = self.cache;

        /**

         *               

         */

        if(!_config.isVertical) {

            $(_config.scrollBarCls).mousedown(function(e){

                _cache.diX = e.pageX - $(this).position().left;

                

                if(this.setCapture) {

                    $(this).mousemove(function(event) {

                        var tagParent = $(event.target).closest(_config.containerCls);

                        self._fnChangePos(event.pageX - _cache.diX,tagParent);

                    });

                    this.setCapture();  //      



                    $(this).mouseup(function() {

                        $(this).unbind('mousemove mouseup');

                        this.releaseCapture(); //      

                    });

                }else {

                     $(document).mousemove(function(event) {

                        var tagParent = $(event.target).closest(_config.containerCls);

                        self._fnChangePos(event.pageX - _cache.diX,tagParent);

                     });

                    $(document).mouseup(function(){

                        $(document).unbind('mousemove mouseup');

                    });

                }

                return false;

            });



        }else {

            $(_config.scrollBarCls).mousedown(function(e){

                _cache.diY = e.pageY - $(this).position().top;

                if(this.setCapture) {

                    $(this).mousemove(function(event){

                        var tagParent = $(event.target).closest(_config.containerCls);

                        self._fnChangePos(event.pageY - _cache.diY,tagParent);

                    });

                    this.setCapture();  //      



                    $(this).mouseup(function() {

                        $(this).unbind('mousemove mouseup');

                        this.releaseCapture(); //      

                    });

                }else {

                    $(document).mousemove(function(event) {

                        var tagParent = $(event.target).closest(_config.containerCls);

                        self._fnChangePos(event.pageY - _cache.diY,tagParent);

                     });

                    $(document).mouseup(function(){

                        $(document).unbind('mousemove mouseup');

                    });

                }

                return false;

            });

        }

    },

    /**

     *       

     * @param xy {string}      

     * @param tagParent {object}    

     *         (      -      ) *       / (      -       )

     */

    _fnChangePos: function(xy,tagParent) {

        var self = this,

            _config = self.config;

        /**

         *               

         */

        if(!_config.isVertical) {

            if(xy < 0) {

                xy = 0;

            }else if(xy > $(tagParent).width() - $(_config.scrollBarCls,tagParent).width()) {



                xy = $(tagParent).width() - $(_config.scrollBarCls,tagParent).width();

            }

            $(_config.scrollBarCls,tagParent).css('left',xy);

            var left = ($(_config.contentCls,tagParent).width() - $(tagParent).width()) * xy /($(tagParent).width() - $(_config.scrollBarCls,tagParent).width());

            $(_config.contentCls,tagParent).css({'left':-left});

        }else {

            if(xy < 0) {

                xy = 0;

            }else if(xy > $(tagParent).height() - $(_config.scrollBarCls,tagParent).height()) {



                xy = $(tagParent).height() - $(_config.scrollBarCls,tagParent).height();

            }

            $(_config.scrollBarCls,tagParent).css('top',xy);

            var top = ($(_config.contentCls,tagParent).height() - $(tagParent).height()) * xy /($(tagParent).height() - $(_config.scrollBarCls,tagParent).height());

            $(_config.contentCls,tagParent).css({'top':-top});

        }

        

    },

    /**

     *        

     */

    _clickScroll: function() {

        var self = this,

            _config = self.config,

            _cache = self.cache;



        $(_config.wrapScrollBarCls).mousedown(function(e){

            /**

             *               

             */

            if(!_config.isVertical) {

                var tagParent = $(e.target).closest(_config.containerCls),

                    relDisX = e.pageX - $(this,tagParent).offset().left;

            

                /**

                 *  relDisX =               (  )-             

                 *  $(_config.scrollBarCls,tagParent).position().left                

                 *  $(_config.scrollBarCls,tagParent).width()         

                 */



                if (relDisX > ($(_config.scrollBarCls,tagParent).position().left + $(_config.scrollBarCls,tagParent).width())) {

                    if(_config.sMoveDis <= relDisX) {

                        self._fnChangePos($(_config.scrollBarCls,tagParent).position().left + _config.sMoveDis,tagParent);

                    }else {

                        //console.log('                  ');

                        self._fnChangePos($(_config.scrollBarCls,tagParent).position().left + relDisX,tagParent);

                    }



                } else if (relDisX < $(_config.scrollBarCls,tagParent).position().left) {

                    self._fnChangePos($(_config.scrollBarCls,tagParent).position().left - _config.sMoveDis,tagParent);

                };

            }else {

                var tagParent = $(e.target).closest(_config.containerCls),

                    relDisY = e.pageY - $(this,tagParent).offset().top;

            

                /**

                 *  relDisX =               (  )-             

                 *  $(_config.scrollBarCls,tagParent).position().left                

                 *  $(_config.scrollBarCls,tagParent).width()         

                 */



                if (relDisY > ($(_config.scrollBarCls,tagParent).position().top + $(_config.scrollBarCls,tagParent).height())) {

                    if(_config.sMoveDis <= relDisY) {

                        self._fnChangePos($(_config.scrollBarCls,tagParent).position().top + _config.sMoveDis,tagParent);

                    }else {

                        //console.log('                  ');

                        self._fnChangePos($(_config.scrollBarCls,tagParent).position().top + relDisY,tagParent);

                    }



                } else if (relDisY < $(_config.scrollBarCls,tagParent).position().top) {

                    self._fnChangePos($(_config.scrollBarCls,tagParent).position().top - _config.sMoveDis,tagParent);

                };

            }

            

        });

    },

    /**

     *       

     */

    _initMouseWheel: function(container) {

        var self = this,

            _config = self.config,

            _cache = self.cache;

        

        var wheelEvent = self._addEvent();

        wheelEvent(container,'mousewheel',function(event){

            var wheelDelta = event.delta;

            if(wheelDelta < 0){



                if(!_config.isVertical) {



                    //      

                    self._fnChangePos($(_config.scrollBarCls,container).position().left + _config.sMoveDis,container);

                }else {



                    //      

                    self._fnChangePos($(_config.scrollBarCls,container).position().top + _config.sMoveDis,container);

                }

                

            }else {



                if(!_config.isVertical) {

                    //    

                    self._fnChangePos($(_config.scrollBarCls,container).position().left -  _config.sMoveDis,container);

                }else {

                    //    

                    self._fnChangePos($(_config.scrollBarCls,container).position().top -  _config.sMoveDis,container);

                }

            }

        });

    },

    /*

     *               

     *           event.delta         0              

     * win7               event.detail          -3             3       

     * win7         event.wheelDelta       -120          120      

     */

    _addEvent: function(){

        var EventProcess = function(event) {

            var type = event.type;

            if(type == 'DOMMouseScroll' || type == 'mousewheel') {

                 event.delta = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;

            }

            if (event.srcElement && !event.target) {

                event.target = event.srcElement;    

            }

            if (!event.preventDefault && event.returnValue !== undefined) {

                event.preventDefault = function() {

                    event.returnValue = false;

                };

            }

            return event;

        }

        if(window.addEventListener) {

            return function(el,type,fn,capture) {

                if (type === "mousewheel" && document.mozHidden !== undefined) {

                    type = "DOMMouseScroll";

                }

                el.addEventListener(type, function(event) {

                    fn.call(this, EventProcess(event));

                }, capture || false);

            }

        }else if (window.attachEvent) {

            return function(el, type, fn, capture) {

                el.attachEvent("on" + type, function(event) {

                    event = event || window.event;

                    fn.call(el, EventProcess(event));    

                });

            }

        }   

    }

 };



 //      

 $(function(){

     new SimulateScroll({});

 });


JSアナログスクロールバーdemoダウンロード