原生JS实现图片网格式渐显与渐隐效果
本文介绍如何使用原生JavaScript结合CSS3实现图片的网格化渐显与渐隐效果。通过将图片分割为多个网格单元,利用background-position控制显示区域,并配合JS的animationFillMode属性及CSS3动画,实现有序或随机的视觉切换效果。
网格渐显效果概述
首先展示最终实现的视觉效果:


开发的小组件支持对图片执行渐显或渐隐操作,且提供有序和随机两种切换模式供选择。
代码结构与网格原理
代码架构采用将属性定义在构造函数内部,而方法定义在原型对象上的方式。若将方法直接写入构造函数,每次调用都会导致重新实例化,例如:
动画属性与实现细节
网格效果的核心原理是获取图片的宽高,根据设定参数将其分割为若干等宽等高的网格单元(此处使用span标签表示)。这些网格通过绝对定位覆盖整个图片区域,每个网格的背景图均设为原图,原理类似于Sprite技术,通过调整background-position属性来显示图片的不同部分。随后,按照预设顺序执行渐显或渐隐逻辑。在动画实现上,JavaScript的animation属性与CSS3的animation属性在取值上存在差异,此次实践让我了解到JS动画对象中包含animationFillMode属性,该属性用于规定动画播放结束或存在延迟未开始时,应应用到元素的样式状态。
当前绑定的触发事件为点击,实际应用中也可替换为其他事件或页面加载时自动触发。该代码稍作修改即可应用于网格形式的轮播图场景。
完整代码实现
以下是完整的源代码示例:
<!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.append(spanNode);
gridArr.push(i);
}
this.gridArr = gridArr;
doc.getElementById('grid_area').append(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>
上述内容介绍了利用原生JavaScript实现图片网格式渐显与渐隐效果的方法,希望能为读者提供有益参考。如有任何疑问,欢迎留言交流,我们将及时回复。同时感谢对本站的支持!
JS在setTimeout或Ajax回调中打开新标签页失败怎么处理
2026-11-05 15:50:12
JS直播协议选型:HLS、FLV与WebRTC的延迟与兼容性对比
2026-11-05 12:16:14
JS实现回到顶部:scrollTop赋值与浏览器兼容性处理
2026-11-04 23:43:35
JS使用classList动态添加、移除和切换CSS类名
2026-11-04 23:40:58
在 D3.js 中实现平滑过渡动画的技巧
2026-11-03 23:46:09
