參照fullPage.js的效果,用自己的想法實現的。
實現的效果:1、全屏滾動,滾動一下齒輪就會滾動全屏。
2、自適應縮放,無論怎么改變窗口的大小,都會保證用一個元素占滿全屏。
下一步計划:
1、改成react組件
2、實現更多的效果
注釋寫的很清楚,基本上知道函數怎么用就可以了。有想法這東西就很簡單。
這里偷懶使用了我之前寫過的一個運動框架(其實就是一個函數),稍加修改就可以在這上面使用。框架相關:點擊這里
注釋非常詳細了,就不說其他的了。直接上代碼:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>index</title> 6 </head> 7 <style> 8 *{ 9 margin: 0; 10 padding: 0; 11 } 12 div{ 13 width: 100%; 14 height: 100%; 15 } 16 .one{ 17 background-color: #1bbc9b; 18 } 19 .sec{ 20 background-color: #4bbfc3; 21 } 22 .thr{ 23 background-color: #7baabe; 24 } 25 </style> 26 <body> 27 <div class="full one">1</div> 28 <div class="full sec">2</div> 29 <div class="full thr">3</div> 30 </body> 31 <script> 32 //添加滾動監聽 33 document.addEventListener('mousewheel',wheel,false); 34 35 //判斷一次滾動是是否完成 36 var isComplete = true; 37 //隱藏滾動條 38 document.body.style.overflow='hidden'; 39 40 //獲取滾動的元素 41 var fullList = document.getElementsByClassName("full"); 42 43 //因為是類數組對象,不是數組對象,所以只能使用call的方式來調用 44 Array.prototype.forEach.call(fullList,function(value){ 45 //獲取一個網頁滿屏的高 46 value.style.height = window.innerHeight +'px'; 47 }) 48 49 //如果窗口大小改變執行的函數 50 window.onresize = function(){ 51 Array.prototype.forEach.call(fullList,function(value){ 52 value.style.height = window.innerHeight +'px'; 53 }); 54 55 //改變窗口大小后,應該仍是一個元素占滿全屏 56 if(document.body.scrollTop % window.innerHeight) 57 { 58 isComplete = false; 59 //根據四舍五入判斷滾動位置 60 let tmp = Math.round(document.body.scrollTop / window.innerHeight)* window.innerHeight; 61 62 //使用運動框架 63 showAnimate(document.body,{'scrollTop':tmp},function(){ 64 isComplete = true; 65 }); 66 } 67 }; 68 69 //滾動函數 70 function wheel(e){ 71 //等待上一個滾動完成 72 if(isComplete){ 73 74 //滾動進行時 75 isComplete = false; 76 77 //判斷是往上滾動還是往下滾動 78 if(e.wheelDelta < 0){ 79 //要滾動到的點 80 let arrivePoint = document.body.scrollTop + window.innerHeight; 81 82 //最大的滾動點 83 let maxBottom = document.body.offsetHeight - window.innerHeight; 84 85 //如果超出了最大的滾動點,則賦值為最大滾動點 86 arrivePoint = arrivePoint > maxBottom ? maxBottom : arrivePoint; 87 88 showAnimate(document.body,{'scrollTop':arrivePoint},function(){ 89 isComplete = true; 90 }); 91 }else{ 92 let arrivePoint = document.body.scrollTop - window.innerHeight; 93 94 //最小滾動點為0 95 arrivePoint = arrivePoint < 0 ? 0 :arrivePoint; 96 showAnimate(document.body,{'scrollTop':arrivePoint},function(){ 97 isComplete = true; 98 }); 99 } 100 } 101 } 102 /** 103 *函數作用:執行動畫 104 *接受參數:obj(需要運動的DOM元素) 105 * json(需要改變的屬性集合,json格式) 106 * fn(回調函數) 107 */ 108 function showAnimate(obj,json,fn){ 109 clearInterval(obj.timer); 110 //表示運動是否都已經停止 111 var flag = true; 112 obj.timer=setInterval(function(){ 113 //循環json 114 for(var i in json){ 115 if(i == 'opacity'){ 116 //獲取透明度值,round四舍五入去除小數點 117 var icur = Math.round(parseFloat(getStyle(obj,i))*100); 118 } 119 else{ 120 //獲取屬性值 121 var icur = parseInt(getStyle(obj,i))||obj[i]; 122 } 123 //緩沖運動,speed隨時變換 124 var speed = (json[i]-icur)/10;//千萬要寫在定時器里面,寫在外面會有意想不到的后果 125 speed = speed > 0 ? Math.ceil(speed):Math.floor(speed);//速度向上或者下取整,防止到不了over位置 126 //如果有一個沒到達終點就是false 127 if(json[i] !== icur){ 128 flag = false; 129 }else{ 130 flag = true; 131 } 132 if(i == 'opacity'){ 133 obj.style.filter = 'alpha(opacity:'+(icur+speed)+')';//IE兼容 134 obj.style.opacity = (icur+speed)/100; 135 }else if(obj[i]||obj[i] == 0){ 136 obj[i] = icur + speed; 137 } 138 else{ 139 obj.style[i] = icur+speed+'px'; 140 } 141 console.log(icur + ' ' + json[i]); 142 } 143 //檢查是否所有的運動都已經停止 144 if(flag){ 145 clearInterval(obj.timer); 146 if(fn){ 147 fn(); 148 } 149 } 150 },13); 151 } 152 /** 153 *函數作用:返回樣式屬性值 154 *接受參數:obj(需要獲取屬性的DOM元素) 155 * attr(需要獲取的屬性名稱) 156 */ 157 function getStyle(obj,attr) 158 { 159 if(obj.currentStyle) 160 { 161 return obj.currentStyle[attr];//IE兼容 162 } 163 else 164 { 165 return getComputedStyle(obj,false)[attr]; 166 } 167 } 168 </script> 169 </html>
