今天的項目需要做到一個介紹頁面,我主動提出走單屏滾頁的風格,畢竟交互性好,逼格也高,具體效果可以參照百度知道書籍預售頁面。
其實現效果就大概是這樣的:
還是老樣子,所有步驟文件可以從我的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>
后續大家可以自行加上鼠標滾輪事件,向上和向下分別觸發上滾頁和下滾頁事件,由于監聽鼠標滾輪事件又是一門小學問,在這里就不贅述了。
但你可以通過這里來獲得包括鼠標滾輪事件在內的全部效果,我把單屏滾頁事件和鼠標滾輪監聽事件都封裝到我的個人插件VaJoyJS中,有興趣的朋友可以從我插件源碼中一窺究竟。
共勉~
文章列表