Correcting teacher:PHPz
Correction status:qualified
Teacher's comments:完成的很好, 继续加油
在样例的基础上添加了左右点击的按钮和事件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>实战: 仿淘宝移动端轮播图-模块</title>
<link rel="stylesheet" href="static/css/slideshow.css" />
</head>
<body>
<div class="slideshow">
<!-- 1. 图片容器 -->
<div class="imgs"></div>
<!-- 2. 按钮容器 -->
<div class="btns"></div>
<!-- 3. 居中左右播放按钮 -->
<div class="midBtns"></div>
</div>
<script type="module">
// 1. 获取图片容器和按钮容器
const imgs = document.querySelector('.imgs');
const btns = document.querySelector('.btns');
const midBtns = document.querySelector('.midBtns');
// console.log(imgs, btns);
// 2. 导入轮播图模块
// (1) 创建图片组: createImgs()
// (2) 创建按钮组: createBtns()
// (3) 创建按钮事件: switchImg()
// (4) 定时器: timePlay()
import { createImgs, createBtns, switchImg, timePlay,createArrows,lrswitchImg } from './static/js/slideshow.js';
// 简化方案例, 使用一个对象来挂载所有导出成员(命名空间方式)
// import * as slideshow from './static/js/slideshow.js';
// 3. 加载成功将图片以及按钮渲染出来
window.onload = () => {
// (1) 创建图片组
createImgs(imgs);
// (2) 创建按钮组
createBtns(imgs, btns);
// 创建中间左右按钮
createArrows(midBtns);
// 事件委托不能滥用,将点击事件绑定到每一个按钮上
// (3) 创建按钮事件
[...btns.children].forEach(function (btn) {
btn.onclick = function () {
switchImg(this, imgs);
};
});
[...midBtns.children].forEach(function (btn){
btn.onclick = function (){
lrswitchImg(this,imgs,btns);
}
})
// [...btns.children].forEach(btn => (btn.onclick = () => switchImg(this, imgs)));
// (4) 定时器: timePlay()
// 0,1,2
// 1,2,0
// 2,0,1
// 0,1,2
// 必须首尾相连,才能实现循环重复播放
// 按钮数组,三个span
const btnArr = [...btns.children];
console.log(btnArr);
// 按钮索引的数组
const btnKeys = Object.keys(btns.children);
console.log(btnKeys);
setInterval(
function (btnArr, btnKeys) {
timePlay(btnArr, btnKeys);
},
2000,
btnArr,
btnKeys
);
};
</script>
</body>
</html>
body {
background-color: #eee;
}
.midBtns {
position: relative;
display: grid;
grid-template-columns: 1fr 1fr;
top: -220px;
padding: 0 10px;
}
.previous,
.next {
width: 50px;
height: 50px;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
.previous {
background-image: url('../images/left.png');
}
.next {
background-image: url('../images/right.png');
place-self: end;
}
/* 轮播图容器 */
.slideshow {
width: 240px;
height: 360px;
}
/* 图片容器 */
.slideshow .imgs {
width: inherit;
height: inherit;
}
/* 图片适应 */
.slideshow img {
width: 100%;
height: 100%;
border-radius: 10px;
/* 默认全隐藏 */
display: none;
}
/* 设置图片的激活状态 */
.slideshow img.active {
display: block;
}
.slideshow img:hover {
cursor: pointer;
}
/* ------ 按钮容器 ------- */
/* 按钮容器 */
.slideshow .btns {
display: flex;
place-content: center;
/* position: relative;
top: -40px; */
transform: translateY(-40px);
}
.slideshow .btns > span {
background-color: rgba(233, 233, 233, 0.5);
height: 16px;
width: 16px;
border-radius: 50%;
margin: 5px;
}
.slideshow .btns > span.active {
background-color: orangered;
}
.slideshow .btns > span:hover {
cursor: pointer;
}
// todo 轮播图模块
// * 1. 图片组
const imgArr = [
{
key: 1,
src: 'static/images/item1.jpeg',
url: 'https://php.cn',
},
{
key: 2,
src: 'static/images/item2.jpeg',
url: 'https://php.cn',
},
{
key: 3,
src: 'static/images/item3.jpeg',
url: 'https://php.cn',
},
];
// * 2. 创建图片组
function createImgs(imgs) {
// 图片资源比较大,所以建议用文档片断来做
const frag = new DocumentFragment();
for (let i = 0; i < imgArr.length; i++) {
// 1. 创建图片元素
// const img = document.createElement('img')
const img = new Image();
// 2. 添加属性
// src
img.src = imgArr[i].src;
// data-key
img.dataset.key = imgArr[i].key;
// class='active': 第一张
if (i === 0) img.classList.add('active');
// 3. 添加事件
img.onclick = () => (location.href = imgArr[i].url);
// 添加图片分二步: 第一步加到内存中的文档片断元素上, 第二步再加到图片容器上
// 4. 添加图片到片断中
frag.append(img);
}
// 5. 将片断添加到图片容器元素中
imgs.append(frag);
}
// * 3. 创建按钮组
function createBtns(imgs, btns) {
// 计算出所有图片的数量,根据这个来创建相同数量的按钮
// console.log(imgs.childElementCount);
let length = imgs.childElementCount;
for (let i = 0; i < length; i++) {
// 1. 生成按钮: <span>
const btn = document.createElement('span');
// 2. 按钮索引: data-key, 必须与图片索引一致
btn.dataset.key = imgs.children[i].dataset.key;
// 3. 第1个按钮处于激活状态
if (i === 0) btn.classList.add('active');
// 4. 添加到容器中
btns.append(btn);
}
}
// * 4. 按钮点击事件
function switchImg(btn, imgs) {
// 1. 去掉图片和按钮的激活状态
[...btn.parentNode.children].forEach(btn => btn.classList.remove('active'));
[...imgs.children].forEach(img => img.classList.remove('active'));
// 2. 将当前的按钮处于激活状态
btn.classList.add('active');
// 3. 根据按钮索引,找到对应的图片
const currImg = [...imgs.children].find(function (img) {
return img.dataset.key == btn.dataset.key;
});
// const currImg = [...imgs.children].find(img => img.dataset.key == btn.dataset.key);
// console.log(currImg);
// 4. 将当前图片处于激活状态(显示出来)
currImg.classList.add('active');
}
// * 5. 定时播放
function timePlay(btnArr, btnKeys) {
// 1. 头部取一个
let key = btnKeys.shift();
// 2. 根据索引找到对应的按钮,再给它自动派发一个点击事件
btnArr[key].dispatchEvent(new Event('click'));
// 3. 把刚才到出的按钮再从尾部进入,实现首尾相连
btnKeys.push(key);
}
// * 6. 创建中间的按钮
function createArrows(midBtns){
const previous = document.createElement('span');
previous.classList.add('previous');
const next = document.createElement('span');
next.classList.add('next');
// 添加到容器中
midBtns.append(previous);
midBtns.append(next);
}
// * 7. 中间按钮(点击左右翻动轮播图)
function lrswitchImg(btn,imgs,botbtns){
let length = imgs.childElementCount;
// 1. 获取当前active状态的图片和按钮
// const imgs = document.querySelectorAll('img');
// console.log(imgs);
const activeImg = [...imgs.children].find(function (img) {
// 去掉图片和按钮的激活状态
if(img.classList.contains('active')){
img.classList.remove('active');
return img;
}
})
;[...botbtns.children].find(function (btn) {
// 去掉按钮的激活状态
if(btn.classList.contains('active')){
btn.classList.remove('active');
}
})
let index = activeImg.dataset.key;
// 判断当前按钮是previous还是next,
// next:当前索引+1,如到最后一个,则返回第0个
if(btn.classList.contains('next')){
index++;
if(index > length){
index = 1;
}
}
// previous: 当前索引-1,如到第一个,则返回最后一个
if(btn.classList.contains('previous')){
if(index > 1){
index--;
}else{
index = length;
}
}
console.log(index);
// 将当前图片设为active
// 3. 根据按钮索引,找到对应的图片和底部按钮
const currImg = [...imgs.children].find(function (img) {
return img.dataset.key == index;
});
const currBtn = [...botbtns.children].find(function (btn) {
return btn.dataset.key == index;
});
// const currImg = [...imgs.children].find(img => img.dataset.key == btn.dataset.key);
// console.log(currImg);
// 4. 将当前图片处于激活状态(显示出来)
currImg.classList.add('active');
currBtn.classList.add('active');
}
export { createImgs, createBtns, switchImg, timePlay,createArrows,lrswitchImg};