文章出處

今天的項目需要做到一個介紹頁面,我主動提出走單屏滾頁的風格,畢竟交互性好,逼格也高,具體效果可以參照百度知道書籍預售頁面

其實現效果就大概是這樣的:

還是老樣子,所有步驟文件可以從我的Github上下載。

原理

滾頁的方式肯定是通過animate來實現,由被點擊的a標簽索引來確定要從哪一頁滾至哪一頁的位置。同時也需要一個全局變量來存儲當前頁面的索引,這樣方便我們通過鼠標滾輪事件來滾頁。

另外這里也調用了回調事件,包括點擊時被激活頁面的回調,以及其它非激活頁面的回調,為了提高復用我們會動用 eval() 來幫忙,不過注意這兩個回調都應該是在滾頁(animate)之后觸發的。

我們先寫下頁面原型:

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>滾頁效果</title>
    <script src="jq.js"></script>
    <style type="text/css">
      body,html {height:100%; margin:0;}
      .screen_wrap{position:relative; height:100%; overflow:hidden;}
      .page{ position:relative; padding:20px;width:100%; height:100%;}
      .page0{ background:yellow;}
      .page1{ background:red;color:white;}
      .page2{ background:green;}
      .page3{ background:blue;color:yellow;}
      .page4{ background:gray; color:white;}
      .bottom_nav{ position:fixed; bottom:0px;padding:10px 0px;width:100%; text-align:center; background:black; opacity:0.8;}
      .bottom_nav a{margin:0px 10px; color:white;}
    </style>
    <script type="text/javascript">
    $(function(){
        
    })
    </script>
  </head>
  <body>
        <div class="screen_wrap" id="screen_wrap">
            <div class="page page0">第一頁</div>
            <div class="page page1">第二頁</div>
            <div class="page page2">第三頁</div>
            <div class="page page3">第四頁</div>
            <div class="page page4">第五頁</div>
        </div>
        <div class="bottom_nav" id="bottom_nav">
        <a href="#!/1">第1頁</a>
        <a href="#!/2">第2頁</a>
        <a href="#!/3">第3頁</a>
        <a href="#!/4">第4頁</a>
        <a href="#!/5">第5頁</a>
        </div>
  </body>
</html>

注意必須設置body,html高度為100%,否則無法設置單頁的高度(原理可以戳這里

接著寫腳本,要讓這幾個page能夠在后續上下運動起來,我們得給它包裹一層div。

$(function(){
    var $a = $("#bottom_nav a");
    var $wrap = $("#screen_wrap");
    var $pages = $wrap.children();
    var $moveWrap = $("<div></div>");
    $moveWrap.css({"position":"relative","height":"100%"});
    $pages.wrapAll($moveWrap); //給五個page外面再包上一層div用以后續上下運動
})

有的朋友可能會好奇,現在不是已經有一層 id="screen_wrap" 的div圍住它們了么,為何還要再裹一層。這是因為screen_wrap主要是滿足我們“單屏”的需求,即通過設置100%的高度以及 overflow:hidden 來防止瀏覽器出現滾動條。

另外我們要考慮到,如果窗口發生了縮放,那么page們運動的幅度就不能按照原先的幅度了,我們得重新給幅度做定義(幅度以當前窗口高度為單位):

$(function(){
    var a_index=0,thetop,win_h;
    var $a = $("#bottom_nav a");
    var $wrap = $("#screen_wrap");
    var $pages = $wrap.children();
    var $moveWrap = $("<div></div>");
    $moveWrap.css({"position":"relative","height":"100%"});
    $pages.wrapAll($moveWrap);
    var getHeight = function(){ //獲取當前窗口高度
        win_h = $.VJ_getWin().h;
        $a.eq(a_index).click(); //防止窗口縮放時頁面布局混亂
    }
    getHeight();
    $(window).on("resize",getHeight); //窗口縮放時,重新初始化上行運動的幅度
})

進一步定義點擊a標簽的觸發事件,讓page滾動起來:

$(function(){
    var a_index=0,thetop,win_h;
    var $a = $("#bottom_nav a");
    var $wrap = $("#screen_wrap");
    var $pages = $wrap.children();
    var $moveWrap = $("<div></div>");
    $moveWrap.css({"position":"relative","height":"100%"});
    $pages.wrapAll($moveWrap);
    var getHeight = function(){
        win_h = $(window).height();
        $a.eq(a_index).click();
      }
    getHeight();
    $(window).on("resize",getHeight);
    $a.click(function(){
        a_index = $a.index(this);
        thetop = a_index * win_h;  //注意之前說的“上下運動的幅度”指的就是這個,主要依賴當前窗口高度
        $pages.parent().animate({"top":-thetop},500);
    })
})

接著添加回調事件,先添加激活頁面的回調:

$(function(){
    var a_index=0,thetop,win_h;
    var $a = $("#bottom_nav a");
    var $wrap = $("#screen_wrap");
    var $pages = $wrap.children();
    var $moveWrap = $("<div></div>");
    $moveWrap.css({"position":"relative","height":"100%"});
    $pages.wrapAll($moveWrap);
    var getHeight = function(){
        win_h = $(window).height();
        $a.eq(a_index).click();
      }
    getHeight();
    $(window).on("resize",getHeight);
    $a.click(function(){
        a_index = $a.index(this);
        thetop = a_index * win_h; 
        $pages.parent().stop().animate({"top":-thetop},500,  //加個.stop() 防止卡頓
            function(){  //animate結束后的回調
                var hasfun = eval("typeof page"+a_index+"==='function'");
                if(hasfun){
                    eval("page"+a_index+"()");  //如果有回調函數則執行該函數
                }
            }
        );
    })
    var page1 = function(){ //激活頁面的回調
        $(".page1").animate({"opacity":"0.2"},2000);
    }
    var page3 = function(){
        $(".page3").animate({"opacity":"0.5"},4000);
    }
})

這里動用了 eval() 來幫忙,關鍵時刻還是蠻好用的,雖然常規還是建議少用eval方法。

我們繼續添加非激活頁面的回調/初始化事件(就是比如你點了page2,切頁后page0-1、page3-4要回調的事件):

$(function(){
  var a_index=0,thetop,win_h,hasfun;
  var $a = $("#bottom_nav a");
  var a_len = $a.length;  //獲得a的個數(其實也就是page個數)
  var $wrap = $("#screen_wrap");
  var $pages = $wrap.children();
  var $moveWrap = $("<div></div>");
  $moveWrap.css({"position":"relative","height":"100%"});
  $pages.wrapAll($moveWrap);
  var getHeight = function(){
      win_h = $(window).height();
      $a.eq(a_index).click();
    }
  getHeight();
  $(window).on("resize",getHeight);
  $a.click(function(){
      a_index = $a.index(this);
      thetop = a_index * win_h; 
      $pages.parent().stop().animate({"top":-thetop},500,
          function(){  //animate結束后的回調
              hasfun = eval("typeof page"+a_index+"==='function'");
              if(hasfun){
                  eval("page"+a_index+"()");  //如果有回調函數則執行該函數
              } 
              for(var i=0;i<a_len;i++){ 
                  if(i==a_index) continue;
                  hasfun = eval("typeof reset"+i+"==='function'"); 
                  if(hasfun){ 
                  eval("reset"+i+"()");  //如果有其它page初始化函數則執行該函數
                  }
              }
          }
      );
  })
  var page1 = function(){
      $(".page1").animate({"opacity":"0.2"},2000);
  }
  var page3 = function(){
      $(".page3").animate({"opacity":"0.5"},4000);
  }
  var reset1 = function(){ //初始化函數
      $(".page1").stop().css({"opacity":"1"});
  }
  var reset3 = function(){
      $(".page3").stop().css({"opacity":"1"});
  }
})

至此,我們要的效果就基本完成了(除了監聽鼠標滾輪事件),我們貼下完整代碼:

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>滾頁效果</title>
    <script src="jq.js"></script>
    <style type="text/css">
      body,html {height:100%; margin:0;}
      .screen_wrap{position:relative; height:100%; overflow:hidden;}
      .page{ position:relative; width:100%; height:100%;}
      .page0{ background:yellow;}
      .page1{ background:red;color:white;}
      .page2{ background:green;}
      .page3{ background:blue;color:yellow;}
      .page4{ background:gray; color:white;}
      .bottom_nav{ position:fixed; bottom:0px;padding:10px 0px;width:100%; text-align:center; background:black; opacity:0.8;}
      .bottom_nav a{margin:0px 10px; color:white;}
    </style>
    <script type="text/javascript">
$(function(){
  var a_index=0,thetop,win_h,hasfun;
  var $a = $("#bottom_nav a");
  var a_len = $a.length;  //獲得a的個數(其實也就是page個數)
  var $wrap = $("#screen_wrap");
  var $pages = $wrap.children();
  var $moveWrap = $("<div></div>");
  $moveWrap.css({"position":"relative","height":"100%"});
  $pages.wrapAll($moveWrap);
  var getHeight = function(){
      win_h = $(window).height();
      $a.eq(a_index).click();
    }
  getHeight();
  $(window).on("resize",getHeight);
  $a.click(function(){
      a_index = $a.index(this);
      thetop = a_index * win_h; 
      $pages.parent().stop().animate({"top":-thetop},500,
          function(){  //animate結束后的回調
              hasfun = eval("typeof page"+a_index+"==='function'");
              if(hasfun){
                  eval("page"+a_index+"()");  //如果有回調函數則執行該函數
              } 
              for(var i=0;i<a_len;i++){ 
                  if(i==a_index) continue;
                  hasfun = eval("typeof reset"+i+"==='function'"); 
                  if(hasfun){ 
                  eval("reset"+i+"()");  //如果有其它page初始化函數則執行該函數
                  }
              }
          }
      );
  })
  var page1 = function(){
      $(".page1").animate({"opacity":"0.2"},2000);
  }
  var page3 = function(){
      $(".page3").animate({"opacity":"0.5"},4000);
  }
  var reset1 = function(){ //初始化函數
      $(".page1").stop().css({"opacity":"1"});
  }
  var reset3 = function(){
      $(".page3").stop().css({"opacity":"1"});
  }
})
    </script>
  </head>
  <body>
        <div class="screen_wrap" id="screen_wrap">
            <div class="page page0">第一頁</div>
            <div class="page page1">第二頁</div>
            <div class="page page2">第三頁</div>
            <div class="page page3">第四頁</div>
            <div class="page page4">第五頁</div>
        </div>
        <div class="bottom_nav" id="bottom_nav">
        <a href="#!/1">第1頁</a>
        <a href="#!/2">第2頁</a>
        <a href="#!/3">第3頁</a>
        <a href="#!/4">第4頁</a>
        <a href="#!/5">第5頁</a>
        </div>
  </body>
</html>
View Code

后續大家可以自行加上鼠標滾輪事件,向上和向下分別觸發上滾頁和下滾頁事件,由于監聽鼠標滾輪事件又是一門小學問,在這里就不贅述了。

但你可以通過這里來獲得包括鼠標滾輪事件在內的全部效果,我把單屏滾頁事件和鼠標滾輪監聽事件都封裝到我的個人插件VaJoyJS中,有興趣的朋友可以從我插件源碼中一窺究竟。

共勉~


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()