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

  先给出效果图:

  

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

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

  

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

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

  毫无疑问渐隐、渐显效果实现部分的代码很有问题,从重构的角度来说,代码内容出现重复就可以提炼出一个新函数。说实话js的原型、原型链的基础知识掌握的比较全,但是在工作中几乎没用到过,可能用的多就就是给引用类型Array扩展一个indexOf()方法等,用原型的概念编写小应用还真是第一次,我也会去下载一些相关插件,看看它们的源码中是如何用原型的概念来编程的。

  下面给出源代码:

  

 <!doctype html>
<head>
<title>网格效果</title>
<style>
@charset "utf-8";
/*css reset*/
html{font-family:"Helvetica Neue",Helvetica,STHeiTi,sans-serif;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;}
body{-webkit-overflow-scrolling:touch;margin:0;}
ul{margin:0;padding:0;list-style:none;outline:none;}
dl,dd{margin:0;}
a{display:inline-block;margin:0;padding:0;text-decoration:none;background:transparent;outline:none;color:#000;}
a:link,a:visited,a:hover,a:active{text-decoration:none;color:currentColor;}
a,dt,dd{-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent;}
img{border:0;}
p{margin:0;}
input,button,select,textarea{margin:0;padding:0;border:0;outline:0;background-color:transparent;}
/*css*/
.origin-pic {
display: inline-block;
width: 200px;
height: 200px;
} .grid-area {
display: inline-block;
position: relative;
width: 200px;
height: 200px;
} .grid {
position: absolute;
} #img1 {
opacity: 1;
width: 200px;
height: 200px;
} @keyframes fadeout{
0% {opacity: 1}
100% {opacity: 0}
} @keyframes fadein{
0% {opacity: 0}
100% {opacity: 1}
}
</style>
</head>
<body>
<div>
<img class="origin-pic" src="./pic.jpg" />
</div>
<div id="grid_area" class="grid-area">
<img id="img1" src="./pic.jpg" />
</div> <script>
var gridSetting = {
'cell': 10, // 行、列数量
'mode': 'fadeout', // 备选参数: fadeout, fadein
'sort': 'random', // 备选参数: inturn, random
'num': 1, // 每次发生动作的网格数,目前只支持1
complete: function() { // 事件完成时的回调函数
console.log('ok!');
}
};
var img1 = document.getElementById('img1');
(function(doc, setting, ele) {
var defaults = {
'speed': 20,
}; function Grid(ele) {
this.ele = ele;
this.settings = Object.assign({}, setting, defaults);
} Grid.prototype = {
constructor: Grid, // 构建UI
_create: function() {
var img = this.ele,
settings = this.settings,
cell = settings.cell,
imgWidth = img.width,
imgHeight = img.height,
gridWidth = imgWidth / cell, // 每个网格宽度
gridHeight = imgHeight / cell, // 每个网格高度
currentTop = 0,
currentLeft = 0,
fragment = doc.createDocumentFragment(),
i = 0,
gridArr = [];
img.style.display = 'none';
for (; i < cell * cell; i++) {
var spanNode = doc.createElement('span');
spanNode.setAttribute('id', i);
spanNode.style.cssText += 'position: absolute;' +
'top: ' + currentTop + 'px;' +
'left: ' + currentLeft + 'px;' +
'margin: 0;' +
'padding: 0;' +
'width: ' + gridWidth + 'px;' +
'height: ' + gridHeight + 'px;' +
'opacity:' + settings.opacity + ';' +
'background: url('+ img.src + ');' +
'background-size: ' + imgWidth + 'px ' + imgHeight + 'px;' +
'background-position: -' + currentLeft + 'px -' + currentTop + 'px;';
if (currentLeft < (imgWidth - gridWidth)) {
currentLeft += gridWidth;
} else {
currentLeft = 0;
currentTop += gridHeight;
}
fragment.appendChild(spanNode);
gridArr.push(i);
}
this.gridArr = gridArr;
doc.getElementById('grid_area').appendChild(fragment);
}, // 渐显、渐隐
_fade: function() {
var gridArr = this.gridArr,
cloneArr = gridArr.slice(0),
length = gridArr.length,
settings = this.settings,
sort = settings.sort,
i = 0;
switch(settings.mode) {
case 'fadeout':
if (sort == 'inturn') {
// 按顺序渐隐
var timer = setInterval(function() {
doc.getElementById(gridArr[i]).style.animation = "fadeout 1s forwards";
i++;
if (i >= settings.cell * settings.cell) {
clearInterval(timer);
settings.complete();
}
}, settings.speed)
} else if (sort == 'random') {
// 随机渐隐
var timer = setInterval(function() {
i = cloneArr.splice(Math.random() * length--, 1);
doc.getElementById(gridArr[i]).style.animation = "fadeout 1s forwards";
if (length == 0) {
clearInterval(timer);
settings.complete();
}
}, settings.speed)
}
break;
case 'fadein':
if (sort == 'inturn') {
// 按顺序渐渐显
var timer = setInterval(function() {
doc.getElementById(gridArr[i]).style.animation = "fadein 1s forwards";
i++;
if (i >= settings.cell * settings.cell) {
clearInterval(timer);
settings.complete();
}
}, settings.speed)
} else if (sort == 'random') {
// 随机渐显
var timer = setInterval(function() {
i = cloneArr.splice(Math.random() * length--, 1);
doc.getElementById(gridArr[i]).style.animation = "fadein 1s forwards";
if (length == 0) {
clearInterval(timer);
settings.complete();
}
}, settings.speed)
}
break;
default:
console.log('配置错误!');
} }, _checkMode: function() {
if (this.settings.mode == 'fadein') {
this.settings.opacity = 0;
} else {
this.settings.opacity = 1;
}
}, }; var gridArea = doc.getElementById('grid_area');
gridArea.addEventListener('click', function() {
var event = new Grid(ele);
event._checkMode();
event._create();
event._fade();
}, false);
})(document, gridSetting, img1);
</script>
</body>
</html>

  2017年6月21日补充:

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

     (function() {
function Person1() {
this.say = function() {
console.log(1)
}
} var Person2 = function() {
this.say = function() {
console.log(2)
}
} Person3 = function() {
this.say = function() {
console.log(3)
}
} var Person4 = function() {
this.say = function() {
console.log(4)
}
} function Person5() {
this.say = function() {
console.log(5)
}
} window.Person4 = Person4;
window.Person5 = Person5;
})()
// Person1 is not defined
// var person1 = new Person1();
// person1.say(); // Person2 is not defined
// var person2 = new Person2();
// person2.say(); //
var person3 = new Person3();
person3.say(); //
var person4 = new Person4();
person4.say(); //
var person5 = new Person5();
person5.say();

原生js实现图片网格式渐显、渐隐效果的更多相关文章

  1. 原生JS—实现图片循环切换的两种方法

    今天我们主要讲讲如何使用原生JS实现图片的循环切换的方法.多余的话我们就不多说了,我们一个一个开始讲吧. 1  原生JS实现图片循环切换 -- 方法一 在上栗子之前我们先简单介绍一下所用的一些知识点. ...

  2. 原生JS—实现图片循环切换及监测鼠标滚动切换图片

    今天我们主要讲讲如何使用原生JS实现图片的循环切换的方法以及如何检测鼠标滚动循环切换图片.多余的话我们就不多说了,我们一个一个开始讲吧. 1  原生JS实现图片循环切换 -- 方法一 在上栗子之前我们 ...

  3. 页面性能优化-原生JS实现图片懒加载

    在项目开发中,我们往往会遇到一个页面需要加载很多图片的情况.我们可以一次性加载全部的图片,但是考虑到用户有可能只浏览部分图片.所以我们需要对图片加载进行优化,只加载浏览器窗口内的图片,当用户滚动时,再 ...

  4. 原生js实现图片轮播思路分析

    一.复习原生js实现图片轮播 1.要点 自动轮播 点击小圆圈按钮,显示相应图片 点击左右箭头,实现向前向后轮播图片 2.实现思路 <div id="container"> ...

  5. 原生JS实现图片循环切换

    <!-- <!DOCTYPE html> <html> <head> <title>原生JS实现图片循环切换 —— 方法一</title&g ...

  6. js简单 图片版时钟,带翻转效果

    js简单 图片版时钟,带翻转效果 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"& ...

  7. 基于原生js的图片延迟加载

    当页面图片比较多的时候,我们通常会做一个延迟加载,避免页面打开时一下子的请求数太多,加载过慢影响用户体验. 如果项目用了jquery框架,则可以直接用 jquery.lazyload.可在jquery ...

  8. 原生JS实现图片预览功能

    html代码: <div class="album-new fr"> <div class="upload-btn btn-new container& ...

  9. 原生js实现图片预览并上传

    最近主导的PC客户端网站重构工程告一段落,下一阶段开始给公司APP开发H5页面,技术栈是react.最近碰到一个需求:需要在H5页面上添加身份证照片,预览并上传.因为要兼容安卓4.4以下版本的手机,所 ...

随机推荐

  1. 关于binary log一点总结[转]

    阅读目录(Content) 1 what's binary log 2 Binary Logging Options and Variables 2.1 基础参数 3 Binary Logging F ...

  2. 打印Fibonacci数列方法汇总(前20项,每行5个)

    NO.1 迭代法 标签:通俗.易懂 思路:先打印第一项.再在循环里面执行fib=fib1+fib2,把fib2赋给fib1,把fib赋给fib2,每行5个可使用if函数(循环次数对5取余). #inc ...

  3. POJ 1743 不可重叠的最长重复子串

    原问题,其实是找最长的相似子串,所谓相似就是一个子串每个值加上一个偏移值可以得到另一个子串. 我们先求原数组的差值数组,对新数组求后缀数组,二分答案,判定是否有某个Height数组中的sa最小值与最大 ...

  4. java 解析xml文档---通过XmlPullParser解析方式

    package com.zx; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayLi ...

  5. 任务十二:学习CSS 3的新特性

    任务目的 学习了解 CSS 3 都有哪些新特性,并选取其中一些进行实战小练习 任务描述 实现 示例图(点击查看) 中的几个例子 实现单双行列不同颜色,且前三行特殊表示的表格 实现正常状态和focus状 ...

  6. jquery虎牙TV3D轮播特效

    css部分: *{ margin: 0px; padding: 0px; } body{ margin: 0px; padding: 0px; text-align: center; } #banne ...

  7. Android 如何本地加载pdf文件

    大部分app打开pdf文件是通过intent调起手机中能打开pdf文件的工具,来查看pdf文件,如果需求是,用户在app内下载好pdf文件后,不通过第三方的工具,本地打开. 这样的需求要怎么实现呢?上 ...

  8. #include<> 和#include“”的区别

    1.< >引用的是编译器的类库路径里面的头文件2."    "引用的是程序目录的相对路径中的头文件,在程序目录的相对路径中找不到该头文件时会继续在类库路径里搜寻该头文件 ...

  9. Java并发包分析——BlockingQueue

    之前因为找实习的缘故,博客1个多月没有写了.找实习的经历总算告一段落,现在重新更新博客,这次的内容是分析Java并发包中的阻塞队列 关于阻塞队列,我之前是一直充满好奇,很好奇这个阻塞是怎么实现.现在我 ...

  10. eclipse--java工程转web工程 以及 java或java web工程转maven工程

    1.  打开工程文件夹,编辑工程的.project文件. 在<natures></natures>中加入 <nature>org.eclipse.wst.commo ...