3分30秒
(function (window, document) {
const methods = { // 公共方法
// 添加元素
appendChild(parent, ...children) {
children.forEach(el => {
parent.appendChild(el);
})
}, // methods.appendChild(parent, el1, el2)
// 获取元素
$(selector, root = document) {
return root.querySelector(selector);
}, // methods.$('#wrap') ==> document.querySelector('#wrap')
// root默认是document 如果有传第二个参数parent => parent.querySelector('#wrap')
// 获取多个元素
$$(selector, root = document) {
return root.querySelectorAll(selector);
},
}
let Img = function(options) {
this._init(options);
this._createElement();
this._bind();
this._show();
}
// 把方法设置在原型上 实例化出来的对象都能访问到原型方法
Img.prototype._init = function({ data, initType, parasitifer }) { // 对象的解构赋值
this.types = ['全部']; // 所有分类
this.all = []; // 所有图片
this.classified = {'全部' : []}; // 按照类型分类后的图片
this.curType = initType; // 当前显示的图片分类
this.parasitifer = methods.$(parasitifer); // 挂载点 wrap
this.imgContainer = null; // 所有图片的容器
this.wrap = null; // 整体容器
this.typeBtnEls = null; // 所有分类按钮组成的数组
this.figures = null; // 所有当前显示的图片组成的数组
this._classify(data); // 接收图片的数据 分类图片
console.log(this.classified);
};
// 图片分类
// all => 类型1 类型2 类型3 类型2
// 0 1 2 3
// classified : {'类型1' :all[0], '类型2 :all[1,3], '类型3' : all[2]}
Img.prototype._classify = function(data) {
let srcs = []; // 记录已经分类过的图片的src
data.forEach(({ title, type, alt, src}, index) => {
if (!this.types.includes(type)) { // includes 查看types所有分类中 有没有当前获取到的分类 没有就加上这个分类
this.types.push(type);
}
if (!Object.keys(this.classified).includes(type)) { // Object.keys 返回对象的所有属性名 并组成数组
this.classified[type] = []; // 如果没有这个类型 给这个类型赋为空数组
}
// 如果图片还没有生成并分类
if (!srcs.includes(src)) {
srcs.push(src); // 记录到srcs中
let figure = document.createElement('figure'); // 生成图片容器
let img = document.createElement('img'); // 放置图片
let figcaption = document.createElement('figcaption'); // 图片显示信息
img.src = src;
img.setAttribute('alt', alt) // 设置img标签的alt属性并赋值
figcaption.innerText = title;
// 使用定义好的方法添加元素
methods.appendChild(figure, img, figcaption);
// 把图片添加到all 所有图片中
this.all.push(figure);
// 把图片添加到对应分类中 从all中获取图片 因为是push进all里面的 所以都是取all的最后一位就对了
this.classified[type].push(this.all.length -1);
}
// 如果图片已经生成分类过了 到srcs(记录已经分类过的图片)中找到图片 添加到对应分类
else {
// findIndex 返回符合条件的第一个位置 如果srcs中有图片全等于src 就把这个图片的下标返回出来 然后图片添加到当前分类中
this.classified[type].push(srcs.findIndex(function(s1) { return s1 === src }))
}
})
}
// 根据分类获取图片
Img.prototype._getImgsByType = function(type) {
// 如果当前分类是全部 直接返回all 所有图片
// 分类不是全部 遍历当前类型的图片 返回all中对应的图片 function(index) { return this.all[index] }
return type === '全部' ? [...this.all] : this.classified[type].map(index => this.all[index])
}
// 生成DOM
Img.prototype._createElement = function() {
let typesBtn = []; // 存放每个按钮的HTML字符串
// 生成每个类型按钮的模板字符串
for (let type of this.types) { // 遍历全部类型的值 全部 JavaScript 前端框架...
// 如果类型 === 当前显示的类型 再给它添加高亮样式类名
typesBtn.push(`<li class="__Img__classify__type-btn${ type === this.curType ? ' __Img__type-btn-active' : '' }">${ type }</li>`);
}
// 整体的模板字符串
let tamplate =
`<ul class="__Img__classify">${ typesBtn.join('') }</ul>
<div class="__Img__img-container"></div>`
// 最大的容器
let wrap = document.createElement('div');
wrap.className = '_Img_container';
wrap.innerHTML = tamplate;
// 选出图片的容器元素 因为要往里面放图片
this.imgContainer = methods.$('.__Img__img-container', wrap);
// 调用设置好的获取图片方法 获取当前显示的分类图片 插入到图片容器中 获取到的图片是数组 用扩展运算符展开
methods.appendChild(this.imgContainer, ...this._getImgsByType(this.curType));
this.wrap = wrap;
// 获取所有分类按钮DOM元素
this.typeBtnEls = methods.$$('__Img__classify__type-btn', wrap)
// 图片墙上的所有图片
this.figures = methods.$$('figure', wrap);
// 遮罩层
let overlay = document.createElement('div');
overlay.className = '_Img_overlay';
overlay.innerHTML = `
<div class="__Img__overlay-prev-btn"></div>
<div class="__Img__overlay-next-btn"></div>
<img src="/assets/images/1.jpg" alt="">`
// 把遮罩层插入到wrap中
methods.appendChild(this.wrap, overlay);
this.overlay = overlay;
// 获取要放大显示的图片元素
this.previewImg = methods.$('img', overlay)
};
// 绑定事件
Img.prototype._bind = function() {
};
// 显示元素
Img.prototype._show = function() {
// 把生成的wrap插入到现实中的挂载点上
methods.appendChild(this.parasitifer, this.wrap);
// 遍历图片墙上的图片 修改样式显示
setTimeout(() => {
this.figures.forEach(figure => {
figure.style.transform = 'scale(1,1)';
figure.style.opacity = '1';
})
})
};
window.$Img = Img; // 将Img构造函数挂载到window上
})(window, document);
请问老师,我显示的效果和视频3分30秒时不一样,鼠标指着图片也没有显示遮罩层,还有一个报错,找不到1.jpg,文件我都是复制源码过来的:Failed to load resource: net::ERR_FILE_NOT_FOUND
正在回答 回答被采纳积分+1
- 参与学习 人
- 提交作业 239 份
- 解答问题 10739 个
本阶段带你深入前端开发的肌理,通过ES6基础知识和前端主流高级框架的学习,助你快速构建企业级移动webAPP应用,进入职场的终极battle
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星