這個插件包含三個部分:HTML結構、CSS代碼和JS代碼。css
HTML結構是固定的,結構以下:html
1 <!--全屏滾動--> 2 <div class="fullpage-container"> 3 <div class="fullpage-pagebox"> 4 <div id="fullpage-page1" class="fullpage-page-vertical"><h1>1</h1></div> 5 <div id="fullpage-page2" class="fullpage-page-vertical"><h1>2</h1></div> 6 <div id="fullpage-page3" class="fullpage-page-vertical"><h1>3</h1></div> 7 <div id="fullpage-page4" class="fullpage-page-vertical"><h1>4</h1></div> 8 <div id="fullpage-page5" class="fullpage-page-vertical"><h1>5</h1></div> 9 <div id="fullpage-page6" class="fullpage-page-vertical"><h1>6</h1></div> 10 </div> 11 </div>
其中元素的類名都是能夠本身配置的,ID也不是必須的。jquery
CSS代碼,只貼出關鍵代碼:chrome
1 *{ 2 padding: 0; 3 margin: 0; 4 } 5 html,body{ 6 height: 100%;/*使html元素和body元素的高度始終等於視口高度*/ 7 } 8 .fullpage-container{ 9 position: relative; 10 height: 100%; 11 overflow: hidden; 12 } 13 .fullpage-pagebox{ 14 height: 100%; 15 position:relative; 16 } 17 18 .fullpage-page-vertical{ 19 height: 100%; 20 position:relative; 21 } 22 23 /***********分頁樣式--此處分頁樣式中的類名是直接寫死在JS代碼中的************/ 24 .fullpage-pagination{ 25 position:fixed; 26 left:17px; 27 top:50%; 28 margin:auto; 29 list-style: none; 30 31 } 32 .fullpage-pagination-item{ 33 width:20px; 34 height:15px; 35 margin:5px; 36 } 37 .fullpage-pagination-item a{ 38 display:block; 39 color: black; 40 text-decoration: none; 41 42 position: relative; 43 height:100%; 44 width:100%; 45 } 46 .fullpage-pagination-item:hover a .fullpage-point{ 47 background-color: black; 48 } 49 .fullpage-point{ 50 position:absolute; 51 width:8px; 52 height:8px; 53 top:0; 54 left:0; 55 bottom:0; 56 right:0; 57 margin: auto; 58 border:1px solid black; 59 border-radius: 4.5px; 60 } 61 .fullpage-point.fullpage-active{ 62 background-color: black; 63 }
JS代碼:app
1 ;(function($,window,document,undefined) { 2 function FullPage(elements,opt) { 3 this.elements = elements;//全屏切換DOM的最外層容器 4 this.defaults = {//默認的配置參數 5 fullpagebox: '.fullpage-pagebox',//全屏頁面的父容器 6 fulleachpage: '.fullpage-page-vertical',//全屏頁面 7 index: 0, //存儲頁面編號 8 duration: 500,//全屏頁面的切換時間 9 easing: "swing",//切換時的Timming Function,與jQuery的animate()方法的取值同樣 10 loop: false,//是否容許循環切換 11 callback: null,//每一屏切換完成時的回調函數 12 paginable: true //是否添加分頁模塊 13 }; 14 this.options = $.extend({},this.defaults,opt || {}); 15 } 16 17 FullPage.prototype = { 18 //初始化函數,插件中的方法都在該函數裏調用 19 initialize: function() { 20 this.fullpagebox = this.elements.find(this.options.fullpagebox); 21 this.fulleachpage = this.elements.find(this.options.fulleachpage); 22 this.pagesnumber = this.fulleachpage.length; 23 this.index = this.options.index; 24 this.slidable = true;//起到優化滾輪事件的做用 25 this.pagination(); 26 this.bindEvent(); 27 28 var position = this.fulleachpage.eq(this.index).position(); 29 this.fullpagebox.css({top: -position.top + "px"}); 30 //alert(this.pagesnumber); 31 }, 32 33 //插件中的事件綁定都由該函數完成 34 bindEvent: function() { 35 var that = this; 36 //鼠標滾輪事件 37 this.elements.on("mousewheel DOMMouseScroll",function(event) { 38 if(that.slidable) { 39 //移除分頁樣式 40 if(that.options.paginable) { 41 that.pagination.find('.fullpage-point').eq(that.index).removeClass('fullpage-active'); 42 } 43 event = event || window.event; 44 var delta = (event.originalEvent.wheelDelta && (event.originalEvent.wheelDelta > 0 ? 1 : -1)) || // chrome & ie 45 (event.originalEvent.detail && (event.originalEvent.detail > 0 ? -1 : 1)); // firefox 46 if (delta > 0) { // 向上滾 47 if(that.index === 0) { 48 if(that.options.loop) { 49 that.index = that.pagesnumber - 1; 50 //that.slide(); 51 } 52 } else if(that.index > 0 && that.index < that.pagesnumber) { 53 that.index--; 54 //that.slide(); 55 } 56 } else if (delta < 0) { // 向下滾 57 58 if(that.index === that.pagesnumber - 1) { 59 if(that.options.loop) { 60 that.index = 0; 61 //that.slide(); 62 } 63 } else if(that.index >= 0 && that.index < that.pagesnumber-1) { 64 that.index++; 65 //that.slide(); 66 } 67 } 68 69 that.slide(); 70 //添加分頁樣式 71 if(that.options.paginable) { 72 that.pagination.find('.fullpage-point').eq(that.index).addClass('fullpage-active'); 73 } 74 //console.log(that.index); 75 } 76 }); 77 //分頁點擊事件 78 if(this.options.paginable) { 79 this.pagination.find('.fullpage-point').click(function() { 80 that.pagination.find('.fullpage-point').eq(that.index).removeClass('fullpage-active'); 81 that.index = $(this).index('.fullpage-point'); 82 //alert(that.index); 83 //alert($(this).index('.fullpage-point')); 84 that.slide(); 85 that.pagination.find('.fullpage-point').eq(that.index).addClass('fullpage-active'); 86 }); 87 } 88 89 //窗口resize事件 90 $(window).on('resize',function() { 91 //var count = that.index; 92 //that.pagination.find('.fullpage-point').eq(that.index).addClass('fullpage-active'); 93 var position = that.fulleachpage.eq(that.index).position(); 94 that.fullpagebox.css({top: -position.top + "px"}); 95 }); 96 97 }, 98 99 //滑動動畫函數,實現頁面向前或向後滑動 100 slide: function() { 101 var that = this; 102 that.slidable = false; 103 //獲取目標屏的位置 104 var position = this.fulleachpage.eq(this.index).position(); 105 //(selector).animate({styles},speed,easing,callback) 106 this.fullpagebox.animate({top: -position.top + "px"},this.options.duration,this.options.easing, function() { 107 that.slidable = true; 108 if(that.options.callback && Object.prototype.toString.call(that.options.callback)=== '[object Function]') { 109 that.options.callback(); 110 } 111 }); 112 }, 113 114 //分頁功能 115 pagination: function() { 116 if(this.options.paginable) { 117 var paginationHTML = ''; 118 for (var i = 0; i < this.pagesnumber; i++) { 119 paginationHTML+='<li class="fullpage-pagination-item"><a href="#"><span class="fullpage-point"></span></a></li>'; 120 } 121 this.pagination = $('<ul class="fullpage-pagination">'+paginationHTML+'</ul>'); 122 this.pagination.appendTo(this.elements); 123 //分頁居中 124 var margintop = -parseInt(this.pagination.css('height'))/2; 125 this.pagination.css('margin-top',margintop+'px'); 126 //alert(pagination.css('margin-top')); 127 this.pagination.find('.fullpage-point').eq(this.index).addClass('fullpage-active'); 128 129 } 130 } 131 }; 132 133 $.fn.fullpage = function(cfg) { 134 var a = new FullPage(this,cfg); 135 //this.cfg = $.extend({},this.options,cfg||{}); 136 a.initialize(); 137 console.log(this); 138 }; 139 //使用該組件時直接用該組件的最外層容器調用fullpage(obj)方法便可 140 //obj是一個對象字面量,接受構造函數中列舉的默認配置參數 141 })(jQuery,window,document)
下面把插件開發過程當中用到的知識點總結一下。框架
定義一個構造函數用來保存和獲取代碼中用到的參數:包括默認的配置參數和調用插件時傳入的參數。dom
在構造函數的原型上添加插件的方法,包括:插件初始化方法,事件綁定方法,切換動畫實現方法和分頁模塊方法。ide
構造函數中使用了jQuery的extend()方法來整合默認參數和傳入的參數。函數
extend()方法有兩種使用方法:oop
1.掛到jQuery上的方法,經過$.extend()調用。本插件中就是用的這種調用方式。
2.掛到jQuery.fn上的方法,經過jQuery的實例對象調用。
先貼兩篇文章:
下面只貼出來使用方法。
一、$.extend(obj) 只傳入一個對象類型參數
這種用法是將obj合併到jQuery的全局對象上去。
例:
1 $.extend({hello: 2 function() { 3 console.log('Hello!'); 4 } 5 }); 6 $.hello();//Hello!
二、$.extend(target, obj1, obj2, obj3,......)
合併obj1~ objN到target對象上。本插件用的就是這種用法。
例:
1 var target = {a:'A',b:'B'}; 2 $.extend(target,{x:'X',y:'Y'},{name:'jack',age:'18'}); 3 4 console.log(target.a);//A 5 console.log(target.y);//Y 6 console.log(target.age);//18
三、$.extend(boolean,target,obj1,obj2,obj3...)
是否深度複製合併對象。第一個參數是boolean類型,爲true時,表示將obj1~ objN深度複製後合併到target中。關於深度複製,是將除null、undefined、window對象、dom對象以及經過繼承建立的對象以外的其它對象深度複製後保存到target中。(測試結果,只有當boolean爲true時纔會將obj1~ objN深度複製後合併到target中;boolean爲false時,target不變,而是將target,obj1~ objN深度複製後合併到返回的新對象中,因此說盡可能不要傳入false值,而僅僅在須要深複製時傳入true)
例:
var target = {a:'A',b:'B'}, obj = {person:{name:'jack',age:18}}; $.extend(true,target,obj); console.log(target.person.age);//18 obj.person.age = 20; console.log(target.person.age)//18
$.extend(false,target,obj);//傳入false,target.person.age報錯,age屬性未定義;target對象沒有變化 console.log(target.person.age);
如下寫法不會報錯
var target = {a:'A',b:'B'}, obj = {person:{name:'jack',age:18}}; var result = $.extend(false,target,obj);//此時傳入false不報錯 console.log(result.person.age);//18 obj.person.age = 20; console.log(result.person.age)//20
4.$.fn.extend(obj)
$.fn = $.prototype =jQuery.prototype
將obj對象的屬性和方法擴展到jQuery全局對象的原型上,那麼jQuery的實例對象就能夠調用這些擴展來的屬性和方法。
例如:
$.fn.extend({say: function() { console.log('OK!'); } }); $("p").on("click",function(){ $(this).say(); //ok });
根據插件的需求在內部將插件劃分爲幾個功能方法並對這些功能方法進行封裝,在編寫插件時只要根據須要調用這些功能方法便可。
在本插件中劃分出的功能方法有:
1.初始化方法 initialize()
顧名思義該方法主要是完成插件的初始化,包括DOM節點的獲取,參數的初始化,其餘功能方法的調用等。
2.事件的綁定方法 bindEvent()
這裏主要是鼠標滾輪事件的綁定和分頁模塊點擊事件的綁定,還有窗口resize事件的綁定。
這裏主要記錄一下經過jQuery的 on() 綁定事件時,傳入事件處理程序的事件對象 event 的注意點。
使用 on() 方法綁定事件時,原生的事件對象保存在 event.originalEvent這個對象中,而 event 是通過jQuery兼容事後的事件對象,它包含如下封裝後通用的事件屬性和方法:
Event 對象的屬性:
屬性 | 初始版本 | 描述 |
---|---|---|
currentTarget | 1.3 | 返回事件冒泡階段中的當前DOM元素。 |
data | 1.1 | 返回綁定事件時傳入的附加數據。 |
delegateTarget | 1.7 | 返回"受委託"調用當前事件處理函數的DOM元素。 |
metaKey | 1.0.4 | 指示觸發事件時是否按下了Meta鍵。 |
namespace | 1.4.3 | 返回觸發事件時指定的命名空間。 |
pageX | 1.0.4 | 返回鼠標相對於當前文檔的x座標。 |
pageY | 1.0.4 | 返回鼠標相對於當前文檔的y座標。 |
relatedTarget | 1.1.4 | 返回事件涉及到的其它DOM元素。 |
result | 1.3 | 返回當前事件綁定的上一個事件處理函數的返回值。 |
target | 1.3 | 最初觸發該事件的DOM元素。 |
timeStamp | 1.2.6 | 返回事件觸發的當前時間與1970年1月1日午夜之間的毫秒數。 |
type | 1.0 | 返回事件的類型。例如:"click"、"focus"等。 |
which | 1.1.3 | 返回觸發事件時按下的鼠標按鈕或鍵盤按鍵。 |
Event 對象的方法:
方法 | 初始版本 | 描述 |
---|---|---|
isDefaultPrevented() | 1.3 | 是否調用了preventDefault()方法。 |
isImmediatePropagationStopped() | 1.3 | 是否調用了stopImmediatePropagation()方法。 |
isPropagationStopped() | 1.3 | 是否調用了stopPropagation()方法。 |
preventDefault() | 1.0 | 阻止觸發事件的默認行爲。 |
stopImmediatePropagation() | 1.3 | 阻止該元素當前觸發事件剩餘的事件處理函數的執行,並中止事件的冒泡傳遞。 |
stopPropagation() | 1.0 | 中止事件的冒泡傳遞。 |
jQuery框架中on()方法的用法介紹,參考:jQuery.on() 函數詳解。
注意:要刪除經過on()綁定的事件,請使用off()函數。若是要附加一個事件,只執行一次,而後刪除本身,請使用one()函數。
3. 切換動畫方法 slide()
主要是用jQuery的animate()方法控制相對定位元素的top屬性實現的。
jQuery框架中 animate() 方法的用法介紹,參考:jQuery.animate() 函數詳解
4.分頁方法 pagination()
分頁功能的HTML結構直接在JS代碼中生成。
this是原生JS中的this,只支持原生JS的屬性和方法,不支持jQuery類型的屬性和方法。
要想使this支持jQuery類型的屬性和方法要用$()函數對原生的this進行包裝:$(this)。
例如:
<p>Click this <span>paragraph.</span></p> <script> $(document).ready(function(){ $("p").on("click",function(){ this.css("color","red");//報錯this.css is not a function $(this).css("color","red");//不報錯 }); }); </script>
index() 返回匹配元素的索引;
eq() 返回對應索引的jQuery對象;
這裏主要記錄index()的用法:
語法:
jQueryObject.index( [ object ] )
若是沒有指定參數object
,則返回 jQueryObject 在其全部同輩元素中的索引位置。
若是object
爲String類型,則將其視做選擇器,返回 jQueryObject 在選擇器所匹配的元素中的索引位置。若是該選擇器不匹配任何元素或者 jQueryObject 不在匹配到的元素內,則返回-1。
若是object
爲DOM元素或jQuery對象,則返回該元素(或該jQuery對象中的第一個元素)在當前jQuery對象所匹配的元素中的索引位置。
例如:
<div id="div1"> <ul id="ul1"> <li id="n1" class="list">item1</li> <li id="n2" class="list">item2</li> <li id="n3" class="list">item3</li> </ul> <ul id="ul2" style="background-color:green;"> <li id="n4" class="list">item4</li> <li id="n5" class="list">item5</li> <li id="n6" class="list">item6</li> </ul> </div>
JS代碼:
$('li').click(function() { console.log($(this).index());//返回this在其全部兄弟元素中的索引 console.log($(this).index('.list'));//返回this在全部類名爲list的元素中的索引 console.log($(this).index($('#n2')));//返回this中id爲n2的元素的索引 }); $('#ul2').click(function() { alert($(this).index());//1 alert($('li').index($('#n6')));//5 });
position()函數用於返回當前匹配元素相對於其被定位的祖輩元素的偏移(不包含margin),也就是相對於被定位的祖輩元素的座標。該函數只對可見元素有效。
所謂"被定位的元素",就是元素的CSS position屬性值爲absolute、relative或fixed(只要不是默認的static便可)。
該函數返回一個座標對象,該對象有一個left屬性和top屬性。屬性值均爲數字,它們都以像素(px)爲單位。
例如:
<style type="text/css"> *{ padding:0; margin:0; } #div2{ position:relative; width:300px; height:200px; background-color:black; overflow:hidden; } #div3{ margin:auto; width:50px; height:50px; background-color:#fff; } </style> <div id="div2"> <div id="div3"></div> </div> <script> var position = $('#div3').position(); console.log(position);//{left:0,top:0} </script>
(完)
參考教程:
二、全屏切換效果