昨天晚上看完歐冠決賽,今天一覺醒來已經是下午,吃過飯就尋思着寫點什麼,正好上週花了好幾個小時溫習原型、原型對象、原型鏈的知識,此次就用原型的概念實現圖片網格式效果(網上大可能是利用jQuery實現,jQuery提供的不少額外的方法和選擇器確實方便許多)。css
先給出效果圖:html
寫的小組件支持圖片的漸顯、漸隱,而且能夠是有序、隨機兩種方式。web
我採用的原型是屬性寫在構造函數內,方法寫在原型對象內。方法寫構造函數內有個問題,就是每次調用這個方法就至關於從新實例化一次,舉個粟子:編程
實現網格效果的原理上是將讀取圖片的寬高,按照設定的參數,分紅等高寬的網格(我用的span標籤表示的網格),網格利用定位鋪滿整個圖片,每一個網格的背景圖都是原圖片,原理同sprite,利用background-position屬性改變顯示區域。接下來就是按照設定的順序實現漸顯或漸隱。漸顯或漸隱用的是JS的animation屬性和CSS3的animation屬性在屬性值上有所區別,此次使用也才知道JS的animation屬性裏有個animationFillMode(規定當動畫不播放時(當動畫完成時,或當動畫有一個延遲未開始播放時),要應用到元素的樣式。)屬性值。app
我綁定的事件是點擊,徹底能夠用其餘事件或頁面加載觸發。dom
毫無疑問漸隱、漸顯效果實現部分的代碼頗有問題,從重構的角度來講,代碼內容出現重複就能夠提煉出一個新函數。說實話js的原型、原型鏈的基礎知識掌握的比較全,可是在工做中幾乎沒用到過,可能用的多就就是給引用類型Array擴展一個indexOf()方法等,用原型的概念編寫小應用還真是第一次,我也會去下載一些相關插件,看看它們的源碼中是如何用原型的概念來編程的。函數
下面給出源代碼:動畫
1 <!doctype html> 2 <head> 3 <title>網格效果</title> 4 <style> 5 @charset "utf-8"; 6 /*css reset*/ 7 html{font-family:"Helvetica Neue",Helvetica,STHeiTi,sans-serif;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;} 8 body{-webkit-overflow-scrolling:touch;margin:0;} 9 ul{margin:0;padding:0;list-style:none;outline:none;} 10 dl,dd{margin:0;} 11 a{display:inline-block;margin:0;padding:0;text-decoration:none;background:transparent;outline:none;color:#000;} 12 a:link,a:visited,a:hover,a:active{text-decoration:none;color:currentColor;} 13 a,dt,dd{-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent;} 14 img{border:0;} 15 p{margin:0;} 16 input,button,select,textarea{margin:0;padding:0;border:0;outline:0;background-color:transparent;} 17 /*css*/ 18 .origin-pic { 19 display: inline-block; 20 width: 200px; 21 height: 200px; 22 } 23 24 .grid-area { 25 display: inline-block; 26 position: relative; 27 width: 200px; 28 height: 200px; 29 } 30 31 .grid { 32 position: absolute; 33 } 34 35 #img1 { 36 opacity: 1; 37 width: 200px; 38 height: 200px; 39 } 40 41 @keyframes fadeout{ 42 0% {opacity: 1} 43 100% {opacity: 0} 44 } 45 46 @keyframes fadein{ 47 0% {opacity: 0} 48 100% {opacity: 1} 49 } 50 </style> 51 </head> 52 <body> 53 <div> 54 <img class="origin-pic" src="./pic.jpg" /> 55 </div> 56 <div id="grid_area" class="grid-area"> 57 <img id="img1" src="./pic.jpg" /> 58 </div> 59 60 <script> 61 var gridSetting = { 62 'cell': 10, // 行、列數量 63 'mode': 'fadeout', // 備選參數: fadeout, fadein 64 'sort': 'random', // 備選參數: inturn, random 65 'num': 1, // 每次發生動做的網格數,目前只支持1 66 complete: function() { // 事件完成時的回調函數 67 console.log('ok!'); 68 } 69 }; 70 var img1 = document.getElementById('img1'); 71 (function(doc, setting, ele) { 72 var defaults = { 73 'speed': 20, 74 }; 75 76 function Grid(ele) { 77 this.ele = ele; 78 this.settings = Object.assign({}, setting, defaults); 79 } 80 81 Grid.prototype = { 82 constructor: Grid, 83 84 // 構建UI 85 _create: function() { 86 var img = this.ele, 87 settings = this.settings, 88 cell = settings.cell, 89 imgWidth = img.width, 90 imgHeight = img.height, 91 gridWidth = imgWidth / cell, // 每一個網格寬度 92 gridHeight = imgHeight / cell, // 每一個網格高度 93 currentTop = 0, 94 currentLeft = 0, 95 fragment = doc.createDocumentFragment(), 96 i = 0, 97 gridArr = []; 98 img.style.display = 'none'; 99 for (; i < cell * cell; i++) { 100 var spanNode = doc.createElement('span'); 101 spanNode.setAttribute('id', i); 102 spanNode.style.cssText += 'position: absolute;' + 103 'top: ' + currentTop + 'px;' + 104 'left: ' + currentLeft + 'px;' + 105 'margin: 0;' + 106 'padding: 0;' + 107 'width: ' + gridWidth + 'px;' + 108 'height: ' + gridHeight + 'px;' + 109 'opacity:' + settings.opacity + ';' + 110 'background: url('+ img.src + ');' + 111 'background-size: ' + imgWidth + 'px ' + imgHeight + 'px;' + 112 'background-position: -' + currentLeft + 'px -' + currentTop + 'px;'; 113 if (currentLeft < (imgWidth - gridWidth)) { 114 currentLeft += gridWidth; 115 } else { 116 currentLeft = 0; 117 currentTop += gridHeight; 118 } 119 fragment.appendChild(spanNode); 120 gridArr.push(i); 121 } 122 this.gridArr = gridArr; 123 doc.getElementById('grid_area').appendChild(fragment); 124 }, 125 126 // 漸顯、漸隱 127 _fade: function() { 128 var gridArr = this.gridArr, 129 cloneArr = gridArr.slice(0), 130 length = gridArr.length, 131 settings = this.settings, 132 sort = settings.sort, 133 i = 0; 134 switch(settings.mode) { 135 case 'fadeout': 136 if (sort == 'inturn') { 137 // 按順序漸隱 138 var timer = setInterval(function() { 139 doc.getElementById(gridArr[i]).style.animation = "fadeout 1s forwards"; 140 i++; 141 if (i >= settings.cell * settings.cell) { 142 clearInterval(timer); 143 settings.complete(); 144 } 145 }, settings.speed) 146 } else if (sort == 'random') { 147 // 隨機漸隱 148 var timer = setInterval(function() { 149 i = cloneArr.splice(Math.random() * length--, 1); 150 doc.getElementById(gridArr[i]).style.animation = "fadeout 1s forwards"; 151 if (length == 0) { 152 clearInterval(timer); 153 settings.complete(); 154 } 155 }, settings.speed) 156 } 157 break; 158 case 'fadein': 159 if (sort == 'inturn') { 160 // 按順序漸漸顯 161 var timer = setInterval(function() { 162 doc.getElementById(gridArr[i]).style.animation = "fadein 1s forwards"; 163 i++; 164 if (i >= settings.cell * settings.cell) { 165 clearInterval(timer); 166 settings.complete(); 167 } 168 }, settings.speed) 169 } else if (sort == 'random') { 170 // 隨機漸顯 171 var timer = setInterval(function() { 172 i = cloneArr.splice(Math.random() * length--, 1); 173 doc.getElementById(gridArr[i]).style.animation = "fadein 1s forwards"; 174 if (length == 0) { 175 clearInterval(timer); 176 settings.complete(); 177 } 178 }, settings.speed) 179 } 180 break; 181 default: 182 console.log('配置錯誤!'); 183 } 184 185 186 }, 187 188 _checkMode: function() { 189 if (this.settings.mode == 'fadein') { 190 this.settings.opacity = 0; 191 } else { 192 this.settings.opacity = 1; 193 } 194 }, 195 196 }; 197 198 var gridArea = doc.getElementById('grid_area'); 199 gridArea.addEventListener('click', function() { 200 var event = new Grid(ele); 201 event._checkMode(); 202 event._create(); 203 event._fade(); 204 }, false); 205 })(document, gridSetting, img1); 206 </script> 207 </body> 208 </html>
2017年6月21日補充:this
關於構造函數在當即執行函數體外的實例化方式:url
1 (function() { 2 function Person1() { 3 this.say = function() { 4 console.log(1) 5 } 6 } 7 8 var Person2 = function() { 9 this.say = function() { 10 console.log(2) 11 } 12 } 13 14 Person3 = function() { 15 this.say = function() { 16 console.log(3) 17 } 18 } 19 20 var Person4 = function() { 21 this.say = function() { 22 console.log(4) 23 } 24 } 25 26 function Person5() { 27 this.say = function() { 28 console.log(5) 29 } 30 } 31 32 window.Person4 = Person4; 33 window.Person5 = Person5; 34 })() 35 // Person1 is not defined 36 // var person1 = new Person1(); 37 // person1.say(); 38 39 // Person2 is not defined 40 // var person2 = new Person2(); 41 // person2.say(); 42 43 // 3 44 var person3 = new Person3(); 45 person3.say(); 46 47 48 // 4 49 var person4 = new Person4(); 50 person4.say(); 51 52 // 5 53 var person5 = new Person5(); 54 person5.say();