原生js实现图片网格式渐显、渐隐效果
昨天晚上看完欧冠决赛,今天一觉醒来已是下午,吃过饭就寻思着写点什么,正好上周花了好几个小时温习原型、原型对象、原型链的知识,这次就用原型的概念实现图片网格式效果(网上大多是利用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实现图片网格式渐显、渐隐效果的更多相关文章
- 原生JS—实现图片循环切换的两种方法
今天我们主要讲讲如何使用原生JS实现图片的循环切换的方法.多余的话我们就不多说了,我们一个一个开始讲吧. 1 原生JS实现图片循环切换 -- 方法一 在上栗子之前我们先简单介绍一下所用的一些知识点. ...
- 原生JS—实现图片循环切换及监测鼠标滚动切换图片
今天我们主要讲讲如何使用原生JS实现图片的循环切换的方法以及如何检测鼠标滚动循环切换图片.多余的话我们就不多说了,我们一个一个开始讲吧. 1 原生JS实现图片循环切换 -- 方法一 在上栗子之前我们 ...
- 页面性能优化-原生JS实现图片懒加载
在项目开发中,我们往往会遇到一个页面需要加载很多图片的情况.我们可以一次性加载全部的图片,但是考虑到用户有可能只浏览部分图片.所以我们需要对图片加载进行优化,只加载浏览器窗口内的图片,当用户滚动时,再 ...
- 原生js实现图片轮播思路分析
一.复习原生js实现图片轮播 1.要点 自动轮播 点击小圆圈按钮,显示相应图片 点击左右箭头,实现向前向后轮播图片 2.实现思路 <div id="container"> ...
- 原生JS实现图片循环切换
<!-- <!DOCTYPE html> <html> <head> <title>原生JS实现图片循环切换 —— 方法一</title&g ...
- js简单 图片版时钟,带翻转效果
js简单 图片版时钟,带翻转效果 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"& ...
- 基于原生js的图片延迟加载
当页面图片比较多的时候,我们通常会做一个延迟加载,避免页面打开时一下子的请求数太多,加载过慢影响用户体验. 如果项目用了jquery框架,则可以直接用 jquery.lazyload.可在jquery ...
- 原生JS实现图片预览功能
html代码: <div class="album-new fr"> <div class="upload-btn btn-new container& ...
- 原生js实现图片预览并上传
最近主导的PC客户端网站重构工程告一段落,下一阶段开始给公司APP开发H5页面,技术栈是react.最近碰到一个需求:需要在H5页面上添加身份证照片,预览并上传.因为要兼容安卓4.4以下版本的手机,所 ...
随机推荐
- struts2 之 ThreadLocal 和 ActionContext
1. ThreadLocal:该类提供了线程局部(thtead-local)变量.threadLocal是一个容器,该容器中存放的数据可以保证线程安全. 案例如: public class Threa ...
- 利用 Forcing InnoDB Recovery 特性解决 MySQL 重启失败的问题
小明同学在本机上安装了 MySQL 5.7.17 配合项目进行开发,并且已经有了一部分重要数据.某天小明在开发的时候,需要出去一趟就直接把电脑关掉了,没有让 MySQL 正常关闭,重启 MySQL 的 ...
- Unity3D 协程 浅谈
协程 理解:协程不是线程,也不是异步执行(知道就行). 1.协程和MonoBehaviour的Update函数一样,也是在MainThread中执行的(一定得明白这句话意思). void Start ...
- git-ftp 用git管理ftp空间
ftp管理不能实现版本控制,而且多电脑工作时,同步很成问题. git-ftp可以完美的解决问题 下面是我的趟坑之路,本机的环境是win10,首先你的机器得装有git. git-ftp的地址https: ...
- JS中Object常用的一些属性和方法
1⃣️属性 刚接触prototype.constructor.proto这三个玩意儿的时候,是不是有点儿傻傻分不清楚的感觉?下面来简单的说下... 举
- Vue 项目实战系列 (二)
上一章节我们已经把项目的初始化工作完成了,接下来我们再来进行具体的代码编写.这一节我们将完成如下的页面. 我们在src/目录下新建一个views文件夹,存放我们的主要页面文件.目录结构如下: cine ...
- 计算机的启动和Linux的启动
计算机的启动和Linux的启动 一 计算机的启动 计算机的启动过程分为四个阶段,分别是:BIOS.MBR.启动管理程序.加载操作系统内核.操作系统启动. 1.1 BIOS 计算机加电后,第一件 ...
- Python安装mysqldb
1.根据Python版本和自己的系统下载mysqldb http://www.codegood.com/downloads
- java中的GC(gabage collection)如何工作
1. “引用记数(reference counting)”是一种简单但速度很慢的垃圾回收技术.每个对象都含有一个引用记数器,当有引用连接至对象时,引用计数加1.当引用离开作用域或被置 为null时,引 ...
- Java之路 ——初识Eclipse
零.大纲 一.前言 二.获取Eclipse 三.运行Eclipse 四.创建及运行第一个Java Project 五.界面介绍 六.如何调试 七.获取插件 八.Eclipse 快捷键 九.总结 一.前 ...