原生js实现图片网格式渐显、渐隐效果

  昨天晚上看完欧冠决赛,今天一觉醒来已是下午,吃过饭就寻思着写点什么,正好上周花了好几个小时温习原型、原型对象、原型链的知识,这次就用原型的概念实现图片网格式效果(网上大多是利用jQuery实现,jQuery提供的很多额外的方法和选择器确实方便许多)。

  先给出效果图:

  

  写的小组件支持图片的渐显、渐隐,并且可以是有序、随机两种方式。

  我采用的原型是属性写在构造函数内,方法写在原型对象内。方法写构造函数内有个问题,就是每次调用这个方法就相当于重新实例化一次,举个粟子:

  

  实现网格效果的原理上是将读取图片的宽高,按照设定的参数,分成等高宽的网格(我用的span标签表示的网格),网格利用定位铺满整个图片,每个网格的背景图都是原图片,原理同sprite,利用background-position属性改变显示区域。接下来就是按照设定的顺序实现渐显或渐隐。渐显或渐隐用的是JS的animation属性和CSS3的animation属性在属性值上有所区别,这次使用也才知道JS的animation属性里有个animationFillMode(规定当动画不播放时(当动画完成时,或当动画有一个延迟未开始播放时),要应用到元素的样式。)属性值

  我绑定的事件是点击,完全可以用其他事件或页面加载触发。

  毫无疑问渐隐、渐显效果实现部分的代码很有问题,从重构的角度来说,代码内容出现重复就可以提炼出一个新函数。说实话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                                             ' ' + 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日补充:

    关于构造函数在立即执行函数体外的实例化方式:

 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();
原文地址:https://www.cnblogs.com/youyouluo/p/6942039.html