2015年4月20日

jQuery學習筆記 第八堂-2(單頁式網頁設計:mousewheel功能)


前陣子可以看到許多單頁式網頁的設計,單頁式網頁就是在一頁裡面把所有要傳達的訊息都傳達完,而網友可以透過捲動捲軸的方式,讓網頁產生類似輪撥的效果。

本堂課主要是延續上一篇jQuery學習筆記 第八堂-1,這次加入了mousewheel的效果後,可以產生一次轉動一頁的效果,點這裡看結果。。

本次會學習到的函數共包含:

CSS
overflow當網頁內容超過時要怎麼處理,可以接visible、hidden、scroll等指令。

jQuery
$( ).mousewheel( ):當滑鼠下上捲動時回報訊息1、當滑鼠向下捲動時回報訊息-1。

為了要達到這樣的效果,我們需要用到一個jQuery的外掛,叫做mousewheel。

mousewheel下載

首先到jQuery官網的地方,上方有一個plugin可以點選


搜尋mousewheel


點選download


點選zip下載


下載後把這個javascript檔和網頁存在相近的資料夾中


最後記得在head中引用這個js檔
<script src="jquery.mousewheel.min.js"></script>

mousewheel的使用方法

回到剛剛的網頁中,點選view homepage


往下拉就可以看到這個外掛的使用說明了


我們來用用看會有什麼效果吧!

我們一樣用上一堂課所學到的console.log( )的用法

回報出來的訊息會像這樣


原來mousewheel這個功能可以讓當滑鼠往上捲動時,回報為「1」,當滑鼠往下捲動時,為報為「-1」。

讓滑鼠滾動一次翻動一頁

透過mousewheel,我們就可以製作如同換頁般的網頁功能

首先,我們建立一個變數n,希望滾動滾輪的時候,可以讓n增加或減少,以此來控制要顯示哪張圖片。

一開始n=1,當我滾動滑鼠滾輪往下時(deltaY= -1)則n++,當我滾動滑鼠滾輪往上時(deltaY= 1)則n--


透過這種寫法,我們n就會開始動了,可是這時候的n沒有上限和下限


我們希望n的數值可以介於1~5之間(也就是我們圖片的編號),所以我們可以把語法加上更多的if,像下面這樣,如果n小於圖片數目的話才可以繼續增加,如果n大於1的話才可以減少。


透過這種寫法,n就一定只會介於1~5之間


這時候,我們就可以開始寫動畫的語法了,讓它根據我們的n跳到指定的頁面


下面那一行animate,是根據我們的n跳到指定頁面的語法;上面那一行stop,同樣是避免動畫的bug產生。

這時候,網頁就會根據我們的滾輪來移動了,可是現在的情況下滾動一次就翻動一頁,很少網友使用滑鼠滾輪是會如此小心翼翼的,一次滾動一個,通常都是一此滾很多個,這樣會變成一滾,就直接到最末頁了,這樣並不是我想要的效果。我們希望的是,滑鼠一滾(不管滾了幾顆),會換一頁。

讓滑鼠滾輪滑一次只換一頁

這時候,我們必須透過一點巧思來達到這個效果,我們新增一個變數叫做moving,當moving等於0時,n才會增加或減少(滾動才有效果),當moving等於1時,怎麼滾n都不會改變(滾動沒有效果)


透過上面這段語法,一開始moving是0,所以n可以改變,n改變之後moving變成1,這時候就把n鎖住了,所以n就不會再改變,因此不管網友怎麼滾動滑鼠都會停留在同一張。

接著,當動畫完成後,我們要把moving變回0,這樣網友才能再滑到其他張圖案,在jQuery的官網同樣有寫到animate這個指令也可以當動畫完成後在執行其他功能


因此,我們就是希望利用這個功能,當動畫完成後,幫我把moving變回0


寫到這裡其實就差不多了,但是使用起來好像「卡卡的」,到底是怎麼回事呢?

消除瀏覽器旁的捲軸

之所以會卡卡的,用一個很重要的原因是因為視窗旁邊的捲軸還在,所以當我們滾動滑鼠中間的滾輪時,它其實是想要先用捲軸來控制我們的視窗,可是我們寫的語法不讓它這麼做,所以兩邊就卡來卡去。

因此,我們要把瀏覽器旁的捲軸消除。消除的方法很簡單,只要在CSS的地方針對body用overflow:hidden這個指令就可以了


如此使用起來就順暢多了!

結合點選導覽列和滾輪

最後一個步驟,是我們要讓被點擊的導覽列和滾輪之間產生關連。這是什麼意思呢?因為我們滾輪抓取的是變數n,而點擊導覽列時抓取的是變數i,這時候會一個問題。在不滾動滾輪的情況下,如果網友點擊導覽列到第4頁,這時候它在往下滾動滾輪時,並不會到第五頁,反而會到第二頁,因為這時候n還是等於1(i = 3;n = 1),他並沒有隨著導覽列被點擊後,變成4,我們現在要解決的就是這個問題,我們希望i這個變數一直都要和n是一致的。

解決的辦法很簡單,讓i+1會等於n就可以了(i因為是eq用的,所以值是介於0-4;n是直接抓圖片編號,所以值是介於1-5,n=i+1)


結果

寫到這裡就完成拉,來看一下我們完整的程式碼吧!
<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>單頁輪撥式網站設計</title>
<!--    匯入jQuery    -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="jquery.mousewheel.min.js"></script>
    <script>
        $(document).ready(function(){
            var num_li=$("li").length//偵測我們有幾個標點(圖片)
            
            //滾動滑鼠滾輪時,移動到上一頁、下一頁的效果
            n=1
            moving=0
            $(window).mousewheel(function(e){
                $("html,body").stop()
                if(moving==0){
                    moving=1
                    if(e.deltaY==-1){
                        if(n<num_li){
                            n++
                        }
                    }else{
                        if(n>1){
                            n--
                        }
                    }
                }
                $("html,body").animate({"scrollTop":$(".p0"+n).offset().top},function(){moving=0})
                console.log(n)
            })
            
            //根據捲軸的位置改變右方導覽列游標的顏色
            $(window).scroll(function(){
                 if($(window).scrollTop()>=$(".p01").offset().top && $(window).scrollTop()<$(".p02").offset().top){
                    $(".nav li").css("background-color","white")//除了被點擊到的游標,其他都恢復成原來的顏色
                    $(".nav li:eq(0)").css("background-color","#46dd46")
                }else if($(window).scrollTop()>=$(".p02").offset().top && $(window).scrollTop()<$(".p03").offset().top){
                    $(".nav li").css("background-color","white")//除了被點擊到的游標,其他都恢復成原來的顏色
                    $(".nav li:eq(1)").css("background-color","#46dd46")
                }else if($(window).scrollTop()>=$(".p03").offset().top && $(window).scrollTop()<$(".p04").offset().top){
                    $(".nav li").css("background-color","white")//除了被點擊到的游標,其他都恢復成原來的顏色
                    $(".nav li:eq(2)").css("background-color","#46dd46")
                }else if($(window).scrollTop()>=$(".p04").offset().top && $(window).scrollTop()<$(".p05").offset().top){
                    $(".nav li").css("background-color","white")//除了被點擊到的游標,其他都恢復成原來的顏色
                    $(".nav li:eq(3)").css("background-color","#46dd46")
                }else if($(window).scrollTop()>=$(".p05").offset().top){
                    $(".nav li").css("background-color","white")//除了被點擊到的游標,其他都恢復成原來的顏色
                    $(".nav li:eq(4)").css("background-color","#46dd46")
                }
            })
                     
            //點選右方導覽列時會到指定圖片
            for(i=0;i<=num_li;i++){
                $(".nav li:eq("+i+")").click({id:i},function(e){
                    $("html,body").stop()
                    $(".nav li").css("background-color","white")//除了被點擊到的游標,其他都恢復成原來的顏色
                    page=e.data.id+1
                    $("html,body").animate({"scrollTop":$(".p0"+page).offset().top})
                    $(".nav li:eq("+e.data.id+")").css("background-color","#46dd46")//被點擊到的游標變色,前面的selector用this也可以
                    n=e.data.id+1
                })
            }
            //一進入網頁時,將導覽列垂直置中計算導覽列置中的位置
           center()
            
           //縮放網頁時,將導覽列垂直置中
            $(window).resize(function(){
                center()
            })
            
            //計算導覽列垂直置中的高度
            function center(){
                pos=$(window).height()/2-$(".nav").height()/2
                $(".nav").css("top",pos)
            }
            
        })
    </script>
<style>
    *{
        padding:0;
        margin:0;
    }
    body{
        overflow: hidden;
    }
/*    插入背景圖片    */
    .p01{
        background-image:url(images/p01.jpg);
        background-size:cover;
        background-repeat: no-repeat;
        height:100vh;
    }
    .p02{
        background-image:url(images/p02.jpg);
        background-size:cover;
        background-repeat: no-repeat;
        height:100vh;
    }
    .p03{
        background-image:url(images/p03.jpg);
        background-size:cover;
        background-repeat: no-repeat;
        height:100vh;
    }
    .p04{
        background-image:url(images/p04.jpg);
        background-size:cover;
        background-repeat: no-repeat;
        height:100vh;
    }
    .p05{
        background-image:url(images/p05.jpg);
        background-size:cover;
        background-repeat: no-repeat;
        height:100vh;
    }
/*    插入導覽列     */
    .nav{
        position: fixed;
        top:50%;
        right:0px;
        cursor:pointer;
    }
    li{
        width:10px;
        height:10px; 
        margin: 10px;
        background-color: white;
        border-radius: 5px;
        box-shadow: 1px 1px 1px rgba(0,0,0,0.5) inset,-1px -1px 1px rgba(0,0,0,0.5) inset;
        list-style-type: none;
    }
    h1{
        font-size:60px;
        color:ghostwhite;
        text-shadow:0px 0px 15px black;
    }
</style>
</head>
<body>
<div class="container">
    <div class="nav">
        <ul>
            <li style="background-color:#46dd46"></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
    </div>
    <div class="p01"><h1>Page 1</h1></div>
    <div class="p02"><h1>Page 2</h1></div>
    <div class="p03"><h1>Page 3</h1></div>
    <div class="p04"><h1>Page 4</h1></div>
    <div class="p05"><h1>Page 5</h1></div>
</div>

</body>
</html>
點這裡看結果

以上內容均為本人在馬老師雲端研究室學習所整理之筆記

1 則留言:

  1. 你好,最近在學網頁程式設計
    看見您的教學非常仔細註解也毫不吝嗇
    自己慢慢也進步了不少
    不知道如何謝謝妳,就在這流言了
    希望言語的讚美能給你一些鼓勵

    回覆刪除