1. 程式人生 > 其它 >隨心所欲的滾動條,遠離產品汪(二)

隨心所欲的滾動條,遠離產品汪(二)

還記得上週咱們說的“隨心所欲滾動條,遠離產品汪”一文嗎?當中介紹了自定義滾動條的基本原理與實現方法,在自定義滾動條實現後,可以通過對滾動條的上下拖動來控制內容區的顯示,使用過的朋友會發現,如果對篇幅較長的內容來說,不停的拖動滾動條來檢視內容,還是比較麻煩的,於是本文在上篇程式碼的基礎上添加了滾輪事件並處理了相應的相容問題。

本文內容

1、原理結構圖

2、滾輪事件及相容問題概要

3、具體實現步驟

4、小結

原理結構圖

為了方便大家熟悉理解,希望大家能夠回顧下上篇“隨心所欲滾動條,遠離產品汪(一)”,本文繼續使用了上篇文章的原理結構圖來輔助理解。

滾輪事件及相容問題概要

在滑鼠上,除了點選、拖拽等事件,當然也少不了滾輪事件了,但是比較有意思的一點是,平常大家碰到相容問題首先想到了IE這個萬年背鍋俠,但是這次還真不是,火狐別樹一幟的湊了一回熱鬧。

1.在滾輪事件中,火狐的的滾動事件是DOMMouseScroll,而其它瀏覽器是mousewheel,這一點是要仔細留意的。

2.在事件物件的相容中。谷歌及主流瀏覽器的事件物件為引數e,而ie事件物件是window.event

3.當滾動滑鼠的時候,火狐瀏覽器通過檢測datail的正負號就可以確定, 而其它瀏覽器IE、谷歌通過檢測wheelDelta正負來確定。

具體實現步驟

滾動事件的新增原理其實與實現自定義滾動條的原理基本一致,只是多了滾輪滾動方向的判斷及滾動值的獲取。

首先,我們需要明白我們的滾輪是作用在誰的身上,根據實際需求來進行事件繫結,當我們滑鼠移入可視區時,會觸發滾輪事件,在移出可視區時則清除滾輪事件,接下來進行具體程式碼操作。

ps:此處為了方便理解使用jQuery來實現,記得引入呦。

較之上篇的實現程式碼,本篇中增加了兩個變數。

1.通過設定變數Judge來判斷滾輪的滾動方向,當Judge為ture時,滾輪向上滾動,當Judge為false時,滾輪向下滾動。

2.設定變數scrY來儲存當前的滾動值,用來計算滾動塊的scrollTop值。

步驟一:給可視區A繫結事件

var srcY = 0;
$('#cn').hover(function(e){ // 移入可視區A        
        $('#cn').on('mousewheel DOMMouseScroll', function(e) {
            e = e.originalEvent || window.event.originalEvent; //繫結事件物件
            scrollFunc(e); //執行scrollFunc(),判斷滾動方向
            var c = $('#cn').height() - $('#bx').height();    
            if (Judge) { // 當滾動向上滾動時,scrY遞減
                scrY--;
            }else{
                scrY++;// 當滾動向下滾動時,scrY遞增
            }
            if (scrY <= 0) { //向上滾動的最大值
                scrY = 0;
            }    
            if (scrY >= c) {//向下滾動的最大值
                scrY = c;
            };
            bx.scrollTop = scrY*10; //為防止滾輪滾動速度過慢,所以乘10增加滾輪滾動速度
            sc.style.top =bx.scrollTop*bxHeight/cnHeight + "px";//與滾動條繫結
        })        
    }, function(){//滑鼠移出可視區A
        //移除滾動事件
        $('#cn').off('mousewheel DOMMouseScroll');


    })

步驟二:判斷滾輪滾動方向

var Judge = true;
function scrollFunc(e){//判斷滾動方向
    if (e.wheelDelta) { //判斷瀏覽器IE,谷歌滑輪事件            
        if (e.wheelDelta > 0) { //當滑輪向上滾動時
            Judge = true;
        }
        if (e.wheelDelta < 0) {
            //當滑輪向下滾動時
            Judge = false;
        }
    } else if (e.detail) { //Firefox滑輪事件
        if (e.detail> 0) { //當滑輪向上滾動時
            Judge = false;
        }
        if (e.detail< 0) { //當滑輪向下滾動時
         Judge = true;
        }
    }
}

完整實現程式碼

完整的實現程式碼在之前實現滾動條的基礎程式碼上新增,並未做調整,大家可以很輕易的分清區別之處,方便大家理解,之後可以根據自己實際需求在這基礎下進行程式碼優化與封裝。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>自定義滾動條(2)</title>
        <style type="text/css">
        .wrap {
            width: 200px;
            height: 150px;
            margin: 0 auto;
        }
        .con {
            float: left;
            overflow: hidden;
            width: 180px;
            height: 150px;
            background: #39f;
        }
        .con p {
            margin: 0;
            color: #fff;
            text-align: center;
            line-height: 20px;
            font-size: 14px;
        }
        .boxscr {
            float: right;
            position: relative;
            width: 20px;
            height: 150px;
            background: #d9ecff;
        }
        .scr {
            position: absolute;
            width: 20px;
            border-radius: 10px;
            background: #c6ccff;
            cursor: pointer;
        }
    </style>
    </head>
    <body>
        <div class="wrap">
            <div class="con" id = "bx">
                <p id="cn">
                    HTML5學堂-自定義滾動條
                    HTML5學堂-自定義滾動條
                    HTML5學堂-自定義滾動條
                    HTML5學堂-自定義滾動條
                    HTML5學堂-自定義滾動條
                    HTML5學堂-自定義滾動條
                    HTML5學堂-自定義滾動條
                    HTML5學堂-自定義滾動條
                    HTML5學堂-自定義滾動條
                    HTML5學堂-自定義滾動條
                    HTML5學堂-自定義滾動條
                    HTML5學堂-自定義滾動條
                    HTML5學堂-自定義滾動條
                </p>
            </div>
            <div class="boxscr" id = "bs">
                <div class="scr" id = "sc"></div>
            </div>
        </div>
<script src="jquery.js" type="text/javascript"></script>
<script>
    var bx = document.getElementById("bx"),
        cn = document.getElementById("cn")
        bs = document.getElementById("bs"),
        sc = document.getElementById("sc"),


        oldY = 0,     // 滑鼠初次點選的Y軸座標
        newY = 0,     // 滑鼠拖動時的Y軸座標
        nowY = 0,     // 滑鼠拖動時滾動條C距父級頂部的高度
        maxY = 0,     // 拖動的最大極限值
        nowDisY = 0, // 點選滾動條C時距父級頂部的高度
        judge = 0,     // 判斷滑鼠滾輪的方向
        scrY = 0;     // 滾輪滾動距離


        bxHeight = bx.clientHeight, // 可視區A高度
        bsHeight = bs.clientHeight, // 滾動區D高度
        cnHeight = cn.offsetHeight; // 滾動塊B的高度


        // 根據滾動塊B實際內容高度控制滾動條C的高度
        scHeight = bxHeight/cnHeight * bxHeight;
        sc.style.height = scHeight + "px";


        // 當滾動塊B實際高度小於可視區時,滾動條隱藏
        if (cnHeight < bxHeight) {
            bs.style.display = "none";
        };


        sc.onmousedown = function(e) {
            oldY = e.clientY;
            nowDisY = sc.offsetTop;         // 當前的滾動條C的top值
            e.preventDefault();
            document.onmousemove = function(e) {
                newY = e.clientY;
                nowY = nowDisY + newY - oldY; // 拖動後的滾動條C的top值
                maxY = bsHeight - scHeight;    // 設定滾動條top極限值


                if (nowY <= 0) {
                    nowY = 0;
                };
                if (nowY >= maxY) {
                    nowY = maxY;
                };


            bx.scrollTop = nowY/maxY * (cnHeight - bxHeight); // 設定滾動塊B的scrollTop值
            sc.style.top = nowY + "px";
            }
 
        }
        document.onmouseup = function() {
            document.onmousemove = null;
        }




        $('#cn').hover(function(e){                                // 移入可視區A        
            $('#cn').on('mousewheel DOMMouseScroll', function(e) {
                e = e.originalEvent || window.event.originalEvent; //繫結事件物件
                scrollFunc(e);                                     //判斷滾動方向
                var c = $('#cn').height() - $('#bx').height();    
                if (Judge) {
                    scrY--;
                }else{
                    scrY++;
                }
                if (scrY <= 0) {
                    scrY = 0;
                }    
                if (scrY >= c) {
                    scrY = c;
                };
                bx.scrollTop = scrY*10;        
                sc.style.top =bx.scrollTop*bxHeight/cnHeight + "px";
            })        
        }, function(){ //滑鼠移出可視區A
            //移除滾動事件
            $('#cn').off('mousewheel DOMMouseScroll');


        })
        //判斷滾動方向
        function scrollFunc(e){        
            if (e.wheelDelta) { //判斷瀏覽器IE,谷歌滑輪事件            
                if (e.wheelDelta > 0) { //當滑輪向上滾動時
                    Judge = true;
                }
                if (e.wheelDelta < 0) {
                    //當滑輪向下滾動時
                    Judge = false;
                }
            } else if (e.detail) { //Firefox滑輪事件
                if (e.detail> 0) { //當滑輪向上滾動時
                    Judge = false;
                }
                if (e.detail< 0) { //當滑輪向下滾動時
                 Judge = true;
                }
            }
        }        
        </script>
    </body>
</html>

實現效果:

小結

到此為止,自定義滾動條的實現已基本完成,其中主要掌握滾動位置的偏移方式及相似比計算便可迎刃而解,同時滾輪事件的相容問題也是不可忽視的,雖然麻煩了一丟丟,但是隻要理清思路,解決起來還是簡單的。

本文系HTML5學堂獨家內容,轉載請在文章開頭顯眼處註明作者和出處“HTML5學堂(http://www.h5course.com/)”