原生js實現圖片網格式漸顯、漸隱效果

  昨天晚上看完歐冠決賽,今天一覺醒來已經是下午,吃過飯就尋思着寫點什麼,正好上週花了好幾個小時溫習原型、原型對象、原型鏈的知識,此次就用原型的概念實現圖片網格式效果(網上大可能是利用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();
相關文章
相關標籤/搜索