按照国际惯例先放效果图
贴代码:
index.html
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>indextitle>
<link rel="stylesheet" href="index.css">
head>
<body>
<div id="wrap">
div>
<script src="index.js">script>
<script src="data.js">script>
<script>
const img=new $Img({
data,
initType:"JavaScript",//默认显示的分类
outWrap:"#wrap"//所有DOM挂载点
});
script>
body>
html>
index.css
*{ margin:0; padding:0; } body{ background: #fafafa; background: url('images/bg.png') } li{ list-style:none; } a{ text-decoration: none; } ::-webkit-scrollbar { display: none; } #wrap{ width: 1065px; margin: 0 auto; padding: 30px; background: rgb(255, 255, 255); border-radius: 2px; margin-top: 100px; } .img_container{ font-size: 10px; } .img_classify_type_btn{ display: inline-block; padding: .2em 1em; font-size: 1.6em; margin-right: 10px; cursor: pointer; border: 1px solid #e95a44; outline: none; color: #e95a44; transition: all .4s; user-select: none;/*文字不允许用户选中*/ border-radius: 2px; } .img_classify_type_btn_active{ background: #e95a44; color: #fff; } .img_pic_container{ position: relative; margin-top: 30px; width: 1005px; display: flex; flex-wrap: wrap; transition: all .6s cubic-bezier(0.77, 0, 0.175, 1);/*动画效果*/ } .img_pic_container figure{ width: 240px; height: 140px; position: absolute; transition: all .6s cubic-bezier(0.77, 0, 0.175, 1); transform: scale(0, 0); opacity: 0; overflow: hidden; border-radius: 2px; user-select: none; } /* 伪元素遮罩层 */ .img_pic_container figure::before { display: block; position: absolute; width: 100%; height: 100%; top: 0; left: 0; z-index: 4; background: rgba(58, 12, 5, 0.5); content: ' '; font-size: 0; opacity: 0; transition: all .3s; cursor: pointer; } /* 图片 */ .img_pic_container figure img { display: block; width: 100%; height: 100%; transition: all .3s; } /* 图片标题 */ .img_pic_container figure figcaption { position: absolute; top: 50%; left: 50%; z-index: 7; opacity: 0; font-size: 1.5em; color: rgb(255, 255, 255); transform: translate(-50%, -50%); transition: all .3s; text-align: center; cursor: pointer; } /* 悬停图片的时候标题显示 */ .img_pic_container figure:hover figcaption{ opacity: 1; } .img_pic_container figure:hover img{ transform: scale(1.1, 1.1); } /* 悬停图片的时候遮罩显示 */ .img_pic_container figure:hover::before{ opacity: 1; } .img_overlay{ position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, .8); display: flex; justify-content: center; align-items: center; opacity: 0; transition: all .3s; display: none; z-index: 99; } .img_overlay_prevbtn, .img_overlay_nextbtn{ position: absolute; width: 50px; height: 50px; border-radius: 50%; border: 2px solid white; text-align: center; line-height: 50px; color: white; font-size: 2rem; cursor: pointer; } .img_overlay_prevbtn{ left: 20px; } .img_overlay_nextbtn{ right: 20px; } .img_overlay_prevbtn:active, .img_overlay_nextbtn:active{ background: rgb(241, 241, 241, .4); } .img_overlay_nextbtn::after{ content: "N"; } .img_overlay_prevbtn::after{ content: "P"; } .img_overlay img { transform: scale(2, 2); }
index.js
(function(window,document){ let canChange=true; let curImgIndex=0;//默认显示的图片索引 //公共方法(便于之后对DOM的操作) const methods={ //同时添加多个子元素,对象简洁表示法 appendChilds(parent,...child){ child.forEach(item=>{ parent.appendChild(item); }) }, //选择单个元素 $(selector,root=document){ return root.querySelector(selector); }, //选择多个元素 $$(selector,root=document){ return root.querySelectorAll(selector); } }; // 构造函数 let Img=function(options){ this._init(options);//初始化,对图片进行分类 this._createElement();//生成DOM this._bind();//绑定事件 this._show();//显示到页面上 } //初始化 Img.prototype._init=function({data,initType,outWrap}){ this.types=["全部"];//全部分类 this.all=[];//所有图片 this.classified={"全部":[]};//分类映射 this.curType=initType;//当前显示的图片分类 this.outWrap=methods.$(outWrap);//所有DOM挂载点 this.imgContainer=null;//图片部分容器(不包括分类按钮) this.wrap=null;//图片区域总容器(包括分类按钮) this.typeBtnEls=null;//分类按钮数组 this.figures=null;//图片数组 this._classify(data);//对图片进行分类 //console.log(this.classified);//打印分类映射表 } //对图片进行分类 Img.prototype._classify=function(data){ let srcs=[];//存储已经生成过的图片,避免重复生成 data.forEach(({type,title,alt,src},index)=>{ // arr.includes(a) 判断数组中是否存在某个值 // 如果分类的数组中,没有当前分类,则添加当前分类 if(!this.types.includes(type)){ this.types.push(type); } //Object.keys(obj) 返回obj中所有属性名组成的数组 //如果属性名中不存在该分类,则添加该分类 if(!Object.keys(this.classified).includes(type)){ this.classified[type]=[]; } //如果该图片没有生成过 if(!srcs.includes(src)){ srcs.push(src); //生成图片 let figure=document.createElement("figure"); let img=document.createElement("img"); let figcaption=document.createElement("figcaption"); img.src=src; img.setAttribute("alt",alt); figcaption.innerText=title; methods.appendChilds(figure,img,figcaption); //添加到图片数组中 this.all.push(figure); //添加到分类映射中 this.classified[type].push(this.all.length-1); }else{ //如果该图片已经生成过,就去srcs数组中找到对应图片 //srcs.findIndex(s1=>s1===src) 遍历src数组,找到元素的值为src的,返回其下标 this.classified[type].push(srcs.findIndex(s1=>s1===src)); } }) } //获取对应分类下的图片 Img.prototype._getImgsByType=function(type){ //如果分类是全部,就返回all数组 //否则就去图片映射表里,找到该分类对应的图片的索引; //通过map遍历this.all数组,找到这些索引对应的图片 return type==="全部"?[...this.all]:this.classified[type].map(index=>this.all[index]); } //生成DOM Img.prototype._createElement=function(){ let typesBtn=[]; //根据分类数组,生成所有分类对应的按钮元素 for(let type of this.types.values()){ typesBtn.push(`
- ${ typesBtn.join("") }
data.js(数据)
const data = [ { type: 'JavaScript', title: 'ES6快速入门', alt: 'ES6快速入门', src: './images/1.jpg' }, { type: 'JavaScript', title: 'Javascript实现二叉树算法', alt: 'Javascript实现二叉树算法', src: './images/2.jpg' }, { type: 'JavaScript', title: 'Canvas绘制时钟', alt: 'Canvas绘制时钟', src: './images/3.jpg' }, { type: 'JavaScript', title: '基于websocket的火拼俄罗斯', alt: '基于websocket的火拼俄罗斯', src: './images/15.jpg' }, { type: '前端框架', title: 'React知识点综合运用实例', alt: 'React知识点综合运用实例', src: './images/4.jpg' }, { type: '前端框架', title: 'React组件', alt: 'React组件', src: './images/5.jpg' }, { type: '前端框架', title: 'Vue+Webpack打造todo应用', alt: 'Vue+Webpack打造todo应用', src: './images/6.jpg' }, { type: '前端框架', title: 'Vue.js入门基础', alt: 'Vue.js入门基础', src: './images/7.jpg' }, { type: '前端框架', title: '使用Vue2.0实现购物车和地址选配功能', alt: '使用Vue2.0实现购物车和地址选配功能', src: './images/8.jpg' }, { type: 'React', title: 'React知识点综合运用实例', alt: 'React知识点综合运用实例', src: './images/4.jpg' }, { type: 'React', title: 'React组件', alt: 'React组件', src: './images/5.jpg' }, { type: 'Vue.js', title: 'Vue+Webpack打造todo应用', alt: 'Vue+Webpack打造todo应用', src: './images/6.jpg' }, { type: 'Vue.js', title: 'Vue.js入门基础', alt: 'Vue.js入门基础', src: './images/7.jpg' }, { type: 'Vue.js', title: '使用Vue2.0实现购物车和地址选配功能', alt: '使用Vue2.0实现购物车和地址选配功能', src: './images/8.jpg' } ]