js
1. == 和 === 的区别是什么
==(普通相等)
- 在类型不相同的情况下,会将运算元先转换成 Number 的值,再进行比较(隐式转换)
jsvar num1 = 0 var num2 = false var num3 = "" console.log(Number(num1), Number(num2), Number(num3)) // 0 0 0 console.log(num1 == num2) // true console.log(num1 == num3) // true console.log(num2 == num3) // true- null ⽐较特殊: null 在进⾏⽐较的时候, 应该是会被当成⼀个对象和原⽣类型进⾏⽐较的
jsvar num4 = null console.log(Number(num4)) // 0 console.log(num1 == num4) // false console.log(num2 == num4) // false console.log(num3 == num4) // false=== (严格不等)
- 在类型不同的情况下,直接返回false
jsvar num1 = 0 var num2 = false var num3 = "" console.log(num1 === num2) // false console.log(num1 === num3) // false console.log(num2 === num3) // false
练习
js
// a == 1 && a == 2 && a == 3 什么时候成立
var a = {
value: 1,
valueOf: function() {
return this.value++
}
}
console.log(a == 1 && a == 2 && a == 3) // true
// b == "1" && b == "2" && b == "3" 什么时候成立
var b = {
value: 1,
toString: function () {
return this.value++
}
}
console.log(b == "1" && b == "2" && b == "3") // true2. 实现倒计时功能

html
<div class="countdown">
<span class="time hour">00</span>
<span class="split">:</span>
<span class="time minute">00</span>
<span class="split">:</span>
<span class="time second">00</span>
</div>Click me to view the code css
css
.countdown {
display: flex;
/* 垂直居中 */
align-items: center;
font-size: 22px;
font-weight: 700;
}
.countdown .time {
width: 60px;
height: 60px;
text-align: center;
line-height: 60px;
color: #fff;
background-color: #f00;
border-radius: 11px;
}
.countdown .split {
padding: 0 6px;
color: #f00;
}Click me to view the code js
js
// 1.获取元素
var hourEl = document.querySelector(".hour")
var minuteEl = document.querySelector(".minute")
var secondEl = document.querySelector(".second")
// 2.获取24:00:00的时间戳
// 🚚 直接设置 不推荐 ❌
// var endDate = new Date("2023-06-07T00:00:00").valueOf()
// ✈️ 先获取当前时间戳,再设置24:00:00
var endDate = new Date()
endDate.setHours(24, 0, 0, 0)
endDate = endDate.getTime()
// 3.封装工具类函数 ---- 解决长度不足的情况
function padLeft(content, count, padStr) {
// 3.1 如果没有传入参数,默认使用当前值
count = count || 2
padStr = padStr || "0"
// 3.2 保证传入的类型是String,可以使用 xx.toString() / String(xx)
content = content.toString()
// 3.3 调用函数 padStart 方法实现填充操作,并返回结果
return content.padStart(count, padStr)
}
// 4.定义函数 ---- 设置倒计时
function setCountdown() {
// 4.1 获取当前时间戳
var nowDate = Date.now()
// 4.2 获取剩下的时间戳 1s = 1000ns
var time = Math.floor((endDate - nowDate) / 1000)
// 4.3 获取具体的 时 / 分 / 秒
var hour = Math.floor(time / 3600)
var minute = Math.floor(time / 60) % 60
var second = time % 60
// 4.4 设置内容
hourEl.textContent = padLeft(hour)
minuteEl.textContent = padLeft(minute)
secondEl.textContent = padLeft(second)
}
// 5.保证第一次进来就调用
setCountdown()
// 6.设置定时器,每隔1s刷新一次
setInterval(setCountdown, 1000)3. 实现返回顶部功能

html
<button class="backTop" title="返回顶部">返回顶部</button>Click me to view the code css
css
body {
height: 1500px;
}
.backTop {
position: fixed;
right: 10px;
bottom: 40px;
width: 50px;
height: 50px;
text-align: center;
color: #fff;
background-color: #f00;
}Click me to view the code js
js
// 1.获取元素
var btnEl = document.querySelector(".backTop")
// 2.默认返回顶部按钮隐藏
btnEl.hidden = true
// 3.监听window的滚动事件
window.onscroll = function () {
// 如果出现拉动滚动条,显示返回顶部按钮,否则隐藏返回顶部按钮
if (this.scrollY > 0) {
btnEl.hidden = false
// 监听返回按钮的点击事件
btnEl.onclick = function () {
// scrollTo(pageX,pageY) 将页面滚动至 绝对坐标
window.scrollTo(0, 0)
// 隐藏返回顶部按钮
this.hidden = true
}
} else {
// 在拉动滚动条位置为0时,保证隐藏返回顶部按钮
btnEl.hidden = true
}
}4. 说说事件冒泡和事件捕获的理解?
事件冒泡: 从最内层的元素向外依次传递的顺序, 默认是事件冒泡
事件捕获: 从外层到内层依次传递的顺序 ,可以通过addEventListener("click",fn,true) 监听事件捕获
5. 说说你对事件委托的理解?
当子元素被点击时,父元素可以通过冒泡可以监听到子元素的点击
并且可以通过event.target获取到当前监听的元素
一个ul中存放多个li,点击某一个li会变成红色 ✅
js
// 🚚 每一个li都监听自己的点击,并且有自己的处理函数(自己的函数)
// 1.获取元素
var liEls = document.querySelectorAll("li")
// 2.循环遍历元素
for (var liEl of liEls) {
// 给liEl绑定点击事件
liEl.onclick = function (event) {
// event.target 事件发生对象 <-> 点击那个元素
// event.currentTarget 当前处理的对象 <-> 绑定的点击事件
event.target.style.color = "#f00"
console.log(event.target) // li
}
}js
// 🔥 事件委托: 它也是一种设计模式,子类发生的事情,我委托给父类,让父类给它做处理,这个叫做事件委托(事件代理)
// 🚚 统一在ul中监听(推荐使用) ✅
// 获取元素
var ulEl = document.querySelector("ul")
// 监听元素的点击
ulEl.onclick = function (event) {
// event.target 事件发生对象 <-> 点击哪个元素
// event.currentTarget 当前处理的对象 <-> 绑定的点击事件
// 如果是 li,变色
if (event.target !== ulEl) {
event.target.style.backgroundColor = "red"
}
}一个ul中存放多个li,点击某一个li会变成红色,其余不变色 ✅
- 思路分析: 通过监听ul元素的点击事件,然后根据点击的元素来添加或移除active类名
js
🚚 方案一:通过循环遍历ul元素的子元素,判断当前点击的元素是否是ul元素本身,
以及子元素是否有active类名,然后根据判断结果来添加或移除active类名。
// 1.获取ul元素
var ulEl = document.querySelector("ul")
// 2.给ul元素绑定点击事件
ulEl.onclick = function (event) {
// 循环遍历ul元素的子元素
for (var liEl of ulEl.children) {
// 如果当前点击的元素不是ul元素本身,并且子元素有active类名,则移除active类名
// event.target !== ulEl && liEl.classList.contains("active") && liEl.classList.remove("active")
// 等价于👆🏻代码
if (event.target !== ulEl && liEl.classList.contains("active")) {
liEl.classList.add("active")
}
}
// 如果当前点击的元素不是ul元素本身,则给当前点击的元素添加active类名
if (event.target !== ulEl) {
// event.target 事件发生对象 <-> 点击那个元素
// event.currentTarget 当前处理的对象 <-> 绑定的点击事件
event.target.classList.add("active")
}
}js
// 1.获取元素
var ulEl = document.querySelector("ul")
// 2.给 ulEls 绑定点击事件
ulEl.onclick = function (event) {
// 🚚 方法二: 直接找到active的li,移除掉active
var activeEl = ulEl.querySelector(".active")
// 如果有这个active类,再移除active
activeEl && event.target !== ulEl && activeEl.classList.remove("active")
// 等价于 👆🏻代码
// if (activeEl && event.target !== ulEl) {
// activeEl.classList.remove("active")
// }
// 2.2 给点击元素添加active
// event.target 事件发生对象 <-> 点击那个元素
// event.currentTarget 当前处理的对象 <-> 绑定的点击事件
if (event.target !== ulEl) {
event.target.classList.add("active")
}
}js
// 1.获取元素
var ulEl = document.querySelector("ul")
var activeEl = null
// 2.给 ulEls 绑定点击事件
ulEl.onclick = function (event) {
// 🚚 方法三: 通过变量记录最新的active元素 ✅
// 2.1 如果有active这个li,就移除他
activeEl && event.target !== ulEl && activeEl.classList.remove("active")
// if (activeEl && event.target !== ulEl) {
// activeEl.classList.remove("active")
// }
// 2.2 给点击元素添加active
// event.target 事件发生对象 <-> 点击那个元素
// event.currentTarget 当前处理的对象 <-> 绑定的点击事件
if (event.target !== ulEl) { // 判断当前处理的对象是不是ulEl
event.target.classList.add("active")
}
// 2.3 记录最新的active对应的li
activeEl = event.target
}6. 鼠标按下去再移动,鼠标抬起来停止移动
Click me to view the code js
js
// 1.获取元素
var boxEl = document.querySelector(".box")
// 2.记录鼠标是否点击下去
var isDown = false
// 3.监听boxEl元素的鼠标按下事件
boxEl.onmousedown = function() {
console.log("鼠标按下去")
isDown = true
}
// 4.监听boxEl元素的鼠标弹起事件
boxEl.onmouseup = function() {
console.log("鼠标弹起")
isDown = false
}
// 5.监听boxEl元素的鼠标被移动事件
boxEl.onmousemove = function() {
if (isDown) {
console.log("鼠标在box上移动")
}
}7. 鼠标经过元素,显示该元素的内容

css
.container {
display: flex;
width: 400px;
height: 200px;
line-height: 200px;
text-align: center;
color: #fff;
font-size: 20px;
}
.container .item {
flex: 1;
}Click me to view the code js
js
// 1.获取元素
var body = document.body
// 2.创建元素
var boxEl = document.createElement("div")
// 3.设置类
boxEl.className = "container"
// 4.插入到body中
body.append(boxEl)
// 5.封装工具类函数 --- 实现随机颜色
function randomColor() {
return `rgb(${Math.floor(Math.random() * 256)},${Math.floor(Math.random() * 256)},${Math.floor(Math.random() * 256)})`
}
// 6.循环遍历元素
for (var i = 0; i < 4; i++) {
// 6.1 创建元素
var divEl = document.createElement("div")
// 6.2 设置类
divEl.className = "item"
// 6.3 设置内容
divEl.textContent = i + 1
// 6.4设置随机颜色
divEl.style.backgroundColor = randomColor()
// 6.5 插入到boxEl中
boxEl.append(divEl)
// 🚚 监听的对象是divEl元素本身
// 6.6 监听divEl元素的鼠标移动事件
divEl.onmouseenter = function (event) {
// console.log(this) // divEl
// event.target 事件发生的对象 <-> 鼠标移动哪个元素上
// event.currentTarget 当前处理的对象 <-> 绑定的点击事件
// console.log(event.target === event.currentTarget) // true
console.log(event.target.textContent)
}
}
// ✈️ 事件委托 推荐使用 ✅
// 7.监听鼠标移动到divEl元素上显示该元素的内容
boxEl.onmouseover = function (event) {
// console.log(this) // boxEl
// event.target 事件发生的对象 <-> 鼠标移动哪个元素上
// event.currentTarget 当前处理的对象 <-> 绑定的点击事件
// console.log(event.target === event.currentTarget) // false
console.log(event.target.textContent)
}如果你在html已经创建好了👇🏻内容

使用👇🏻
Click me to view the code js
js
// 1.获取元素
var boxEl = document.querySelector("div")
// 2.封装工具类函数 --- 实现随机颜色
function randomColor() {
return `rgb(${Math.floor(Math.random() * 256)},${Math.floor(Math.random() * 256)},${Math.floor(Math.random() * 256)})`
}
// 3.循环遍历元素
for (var divEl of boxEl) {
// 3.1 创建元素
divEl.textContent = i + 1
// 3.2 设置随机颜色
divEl.style.backgroundColor = randomColor()
// 🚚 监听的对象是divEl元素本身 onmouseenter 不支持冒泡(不能使用事件委托)
// 3.3 监听divEl元素的鼠标移动事件
divEl.onmouseenter = function (event) {
// console.log(this) // divEl
// event.target 事件发生的对象 <-> 鼠标移动哪个元素上
// event.currentTarget 当前处理的对象 <-> 绑定的点击事件
// console.log(event.target === event.currentTarget) // true
console.log(event.target.textContent)
}
}
// ✈️ 事件委托 推荐使用 ✅ onmouseover 支持冒泡(不能使用事件委托)
// 4.监听鼠标移动到divEl元素上显示该元素的内容
boxEl.onmouseover = function (event) {
// console.log(this) // boxEl
// event.target 事件发生的对象 <-> 鼠标移动哪个元素上
// event.currentTarget 当前处理的对象 <-> 绑定的点击事件
// console.log(event.target === event.currentTarget) // false
console.log(event.target.textContent)
}8. 实现搜索功能, 点击搜索按钮 / 按回车键 直接搜索
html
<input type="text">
<button>搜索</button>js
// 1.获取元素
var inputEl = document.querySelector("input")
var btnEl = document.querySelector("button")
// 2.监听btnEl元素的点击事件
btnEl.onclick = function () {
console.log(`搜索${inputEl.value}`)
}
// 3.监听inputEl元素的键盘按下的回车事件
inputEl.onkeydown = function (event) {
// console.log(event.key) // "Enter"
// console.log(event.code) // "Enter"
// 如果在inputEl元素中按下回车键,直接搜索
if (event.code === "Enter") {
console.log(`搜索${inputEl.value}`)
}
}9. 按下 s 的时候,搜索自动获取焦点
js
// 1.获取元素
var inputEl = document.querySelector("input")
// 2.监听document的键盘按下事件
document.onkeydown = function (event) {
// console.log(event.code) // "KeyS" 推荐使用 ✅
// console.log(event.key) // "s" || "S" 区分大小写
if (event.code === "KeyS") {
// 按下s(S)键,input表单自动聚焦
inputEl.focus()
}
}10. 轮播消息提示

html
<div class="tip-bar">
<img src="./images/avatar.png" alt="">
<span>coderccb对这件商品感兴趣</span>
</div>
css
.tip-bar {
display: inline-flex;
align-items: center;
height: 30px;
background-color: rgba(0, 0, 0, .4);
border-radius: 16px;
box-sizing: border-box;
}
.tip-bar img {
width: 30px;
height: 30px;
border-radius: 50%;
}
.tip-bar span {
margin: 0 8px;
font-size: 14px;
color: #333;
}按顺序每隔3s刷新一次数据
Click me to view the code js
js
// 1.从服务器拿到数据 ajax/fetch请求
var tipList = [
{
icon: "https://tse4-mm.cn.bing.net/th/id/OIP-C.0KvO81VQ-QeWbGVRhT8E8wHaHa?w=209&h=209&c=7&r=0&o=5&dpr=2&pid=1.7",
title: "167***348对这件商品感兴趣"
},
{
icon: "https://p.qqan.com/up/2021-2/16123225767181974.jpg",
title: "183***138对这件商品感兴趣"
},
{
icon: "https://tse3-mm.cn.bing.net/th/id/OIP-C.aQRoVI_BQCO4ua8drGqu-gHaFj?w=257&h=193&c=7&r=0&o=5&dpr=2&pid=1.7",
title: "193***788对这件商品感兴趣"
}
]
// 2.动态切换数据
// 2.1 获取元素
var tipbarEl = document.querySelector(".tip-bar")
var imgEl = tipbarEl.querySelector("img")
var spanEl = tipbarEl.querySelector("span")
// 2.2 记住当前索引变量
var currentIndex = Math.floor(Math.random() * tipList.length)
// 2.2 每隔3s刷新一次数据
setInterval(function () {
// 2.2.1 如果当前索引 等于 数组长度,默认当前索引为0
if (currentIndex === tipList.length) {
currentIndex = 0
}
// 2.2.2 更新数据
imgEl.src = tipList[currentIndex].icon
spanEl.textContent = tipList[currentIndex].title
// 2.2.3 当前索引自增
currentIndex++
}, 3000)随机每隔3s刷新一次数据
Click me to view the code js
js
// 1.从服务器拿到数据 ajax/fetch请求
var tipList = [
{
icon: "https://tse4-mm.cn.bing.net/th/id/OIP-C.0KvO81VQ-QeWbGVRhT8E8wHaHa?w=209&h=209&c=7&r=0&o=5&dpr=2&pid=1.7",
title: "167***348对这件商品感兴趣"
},
{
icon: "https://p.qqan.com/up/2021-2/16123225767181974.jpg",
title: "183***138对这件商品感兴趣"
},
{
icon: "https://tse3-mm.cn.bing.net/th/id/OIP-C.aQRoVI_BQCO4ua8drGqu-gHaFj?w=257&h=193&c=7&r=0&o=5&dpr=2&pid=1.7",
title: "193***788对这件商品感兴趣"
}
]
// 2.动态切换数据
// 2.1 获取元素
var tipbarEl = document.querySelector(".tip-bar")
var imgEl = tipbarEl.querySelector("img")
var spanEl = tipbarEl.querySelector("span")
// 2.2 每隔3s刷新一次数据
setInterval(function () {
// 2.2.1 记住当前随机生成的索引
var currentIndex = Math.floor(Math.random() * tipList.length)
// 2.2.2 如果当前索引 等于 数组长度,默认当前索引为0
if (currentIndex === tipList.length) {
currentIndex = 0
}
// 2.2.3 更新数据
imgEl.src = tipList[currentIndex].icon
spanEl.textContent = tipList[currentIndex].title
// 2.2.4 当前索引自增
currentIndex++
}, 3000)11. 关闭隐藏消息

Click me to view the code css
css
/* 样式重置 */
html,
body,
div,
img,
span {
/* 去除默认样式 */
margin: 0;
padding: 0;
}
/* 布局样式 */
.top-bar {
display: flex;
align-items: center;
height: 45px;
line-height: 45px;
text-align: center;
color: #fff;
font-size: 14px;
background-color: #333;
/* 防止高度为0,其他内容没有隐藏 */
overflow: hidden;
/* 添加过渡动画 */
transition: height .3s ease-out;
}
.top-bar .close {
width: 8%;
}
.top-bar .close img {
width: 10px;
height: 10px;
transition: prop time;
}
.top-bar .logo {
width: 30px;
height: 30px;
margin: 0 4px;
}
.top-bar span {
flex: 1;
height: 45px;
padding-top: 2px;
box-sizing: border-box;
}
.top-bar .btn {
width: 25%;
height: 45px;
padding-top: 2px;
box-sizing: border-box;
background-color: #F63515;
}html
<div class="top-bar">
<div class="close">
<img src="https://m.360buyimg.com/mobilecms/jfs/t19480/10/1439571805/820/787bec2c/5ac9d730N04e6d766.png" alt="">
</div>
<img src="https://img13.360buyimg.com/img/jfs/t1/185008/26/33606/2587/641973cbFd5acd3e9/ad0294917f47e6b8.png"
alt="京东" class="logo">
<span>打开京东APP,实惠又轻松</span>
<div class="btn">立即打开</div>
</div>🚚: 直接删除,没有动画效果
Click me to view the code js
js
// 1.获取元素
var topbarEl = document.querySelector(".top-bar")
var closeEl = topbarEl.querySelector(".close")
// 2.监听closeEl元素的点击事件
closeEl.onclick = function () {
// 删除元素
topbarEl.remove()
}🚚: 有动画效果,需要设置高度为0,定时器移除,但是定时器的时间必须跟动画保持一致
Click me to view the code js
js
// 1.获取元素
var topbarEl = document.querySelector(".top-bar")
var closeEl = topbarEl.querySelector(".close")
// 2.监听closeEl元素的点击事件
closeEl.onclick = function () {
// 2.1 有动画效果,需要设置高度为0
topbarEl.style.height = 0
// 2.2 定时器移除,但是定时器的时间必须跟动画保持一致
setTimeout(function () {
topbarEl.remove()
}, 300)
}🚚: 有动画效果,需要设置高度为0,利用动画结束事件 transitionend 清除元素
Click me to view the code js
js
// 1.获取元素
var topbarEl = document.querySelector(".top-bar")
var closeEl = topbarEl.querySelector(".close")
// 2.监听closeEl元素的点击事件
closeEl.onclick = function () {
// 1.有动画效果,需要设置高度为0
topbarEl.style.height = 0
}
// ✈️: 2.利用动画结束事件 transitionend事件的事件处理函数,在某个CSS过渡完成时触发。
topbarEl.ontransitionend = function() {
// 删除元素
this.remove()
}12. 侧边栏展示

html
<div class="tool-bar">
<div class="item">
<i class="icon"></i>
<div class="name">购物车</div>
</div>
<div class="item">
<i class="icon"></i>
<div class="name">收藏</div>
</div>
<div class="item">
<i class="icon"></i>
<div class="name">限时活动</div>
</div>
<div class="item">
<i class="icon"></i>
<div class="name">大礼包</div>
</div>
</div>通过css实现效果
Click me to view the code css
css
/* 样式重置 */
/* 样式重置 */
html,
body,
div,
i {
/* 去除默认样式 */
margin: 0;
padding: 0;
}
.tool-bar {
position: fixed;
top: 30%;
right: 0;
width: 35px;
display: flex;
/* 改变主轴的方向 y */
flex-direction: column;
}
.tool-bar .item {
position: relative;
height: 35px;
margin-bottom: 1px;
background-color: #7a6e6e;
border-radius: 3px 0 0 3px;
/* 鼠标小手 */
cursor: pointer;
}
/* ✈️ 通过js实现鼠标经过元素,减少csS代码!!! */
.tool-bar .item:hover .name,
.tool-bar .item:hover .icon {
background-color: #cd1926;
}
.tool-bar .item:hover .name {
width: 62px;
}
.tool-bar .item .icon {
display: inline-block;
width: 100%;
height: 100%;
background-image: url(./images/toolbars.png);
/* 🔥 由于精灵图排放位置,所以x轴为(-48px)不变,y轴(0) *50 */
background-position: -48px 0;
}
/* ✈️ 通过js实现精灵图的排放位置,减少csS代码!!! */
.tool-bar .item:nth-child(2) .icon {
background-position: -48px -50px;
}
.tool-bar .item:nth-child(3) .icon {
background-position: -48px -100px;
}
.tool-bar .item:nth-child(4) .icon {
background-position: -48px -150px;
}
.tool-bar .item .name {
position: absolute;
top: 0;
right: 35px;
width: 0;
/* width: 62px; */
height: 35px;
line-height: 35px;
text-align: center;
font-size: 12px;
color: #fff;
background-color: #7a6e6e;
border-radius: 3px 0 0 3px;
/* 在默认收缩 width为0 的情况下,隐藏文字 */
/* 🚚 隐藏文字 */
/* overflow: hidden; */
/* 🚚 定位层叠 */
z-index: -1;
/* 添加动画 */
transition: width .2s ease;
}动态给 icon 设置backgroundPosition


Click me to view the code css
js
// 1.获取元素
var toolbarEl = document.querySelector(".tool-bar")
var iconEls = document.querySelectorAll(".icon")
// 2.循环遍历元素,给每个 icon 设置 background-position
for (var i = 0; i < iconEls.length; i++) {
iconEls[i].style.backgroundPosition = `-48px ${-50 * i}px`
}实现鼠标进入动画
- 事件委托 onmouseover / onmouseout 鼠标经过/离开事件
Click me to view the code js
js
// 1.获取元素
var toolbarEl = document.querySelector(".tool-bar")
// 2.监听toolbarEl的鼠标经过事件
toolbarEl.onmouseover = function (event) {
handleMouseEvent(event, "#cd1926", "62px")
}
// 3.监听toolbarEl的鼠标离开事件
toolbarEl.onmouseout = function (event) {
handleMouseEvent(event, "#7a6e6e")
}
// 4.封装工具类函数 ---- 实现鼠标在元素上经过和离开
function handleMouseEvent(event, backgroundColor, width) {
// event.target 事件发生的对象 <-> 鼠标移动哪个元素上
// event.currentTarget 当前处理的对象 <-> 绑定的点击事件
if (event.target !== this) {
/* // 获取唯一的item
var itemEl = null
if (event.target.classList.contains("item")) {
itemEl = event.target
} else {
itemEl = event.target.parentElement
} */
// 获取itemEl元素(// 等价于👆🏻 如果当前元素有item这个类,就直接返回当前元素,如果没有,就返回当前元素的父元素)
var itemEl = event.target.classList.contains("item") ? event.target : event.target.parentElement
// 获取iconEl元素
var iconEl = itemEl.children[0]
// 获取nameEl元素
var nameEl = itemEl.children[1]
// 设置iconEl的背景颜色
iconEl.style.backgroundColor = backgroundColor
// 设置nameEl的背景颜色
nameEl.style.backgroundColor = backgroundColor
// 设置nameEl的宽度(将值设置为空字符串,那么会使用CSS的默认样式),如果不传入参数,使用默认值 输入
nameEl.style.width = width || ""
}
}- mouseenter(不能使用事件委托)
Click me to view the code css
js
// 1.获取元素
var itemEls = document.querySelectorAll(".item")
// 2.循环遍历元素
for (var itemEl of itemEls) {
// 2.1 监听itemEl元素的鼠标经过事件
itemEl.onmouseenter = function (event) {
handleMouseEvent(event, "#cd1926", "62px")
}
// 2.2 监听itemEl元素的鼠标离开事件
itemEl.onmouseleave = function (event) {
handleMouseEvent(event, "#7a6e6e")
}
// 2.3 封装工具类函数 --- 实现在元素的鼠标经过/离开
function handleMouseEvent(event, backgroundColor, width) {
// 获取iconEl,nameEl元素
var iconEl = this.children[0]
var nameEl = this.children[1]
// 设置iconEl,nameEl的背景颜色
iconEl.style.backgroundColor = backgroundColor
nameEl.style.backgroundColor = backgroundColor
// 设置nameEl的宽度(将值设置为空字符串,那么会使用CSS的默认样式)
nameEl.style.width = width || ""
}
}13. 说出mouseenter和mouseover的区别
mouseenter
不会冒泡
进入子元素的时候不会有任何行为
mouseover
会进行冒泡行为
进入子元素 会先out父元素 在over子元素 在over父元素
14. 说说load和DOMContentLoaded的区别
load: 浏览器加载完所有的HTML 还加载完所有的外部资源 样式 图⽚等
DOMContentLoaded: HTML⽂档所有资源都加载完成 并构建了DOM树 但是⼀些外部资源还没有加载完成 如图⽚的src
15. 王者荣耀tabControl切换

Click me to view the code html
html
<div class="tab_control">
<div class="item active">精品栏目</div>
<div class="line"></div>
<div class="item">赛事精品</div>
<div class="line"></div>
<div class="item">英雄攻略</div>
</div>Click me to view the code css
css
/* 样式重置 */
html,
body,
div {
/* 去除默认样式 */
margin: 0;
padding: 0;
}
/* 布局样式 */
.tab_control {
display: flex;
width: 872px;
/* margin: 0 auto; */
/* margin-bottom: 13px; */
margin: 100px auto 13px;
background-color: #f5f5f5;
}
.tab_control .item {
flex: 1;
height: 32px;
box-sizing: border-box;
text-align: center;
line-height: 29px;
font-size: 14px;
color: #999;
border-bottom: 3px solid transparent;
/* 鼠标小手 */
cursor: pointer;
/* 添加动画 */
transition: all .3s ease-in;
}
.tab_control .item.active {
color: #333;
border-color: #f3c258;
}
.tab_control .line {
width: 1px;
height: 20px;
margin: 5px 0;
background-color: #e1e1e1;
}Click me to view the code js
js
// 1.获取元素
var tabControlEl = document.querySelector(".tab_control")
var activeEl = tabControlEl.querySelector(".active")
// 2.监听tabControlEl元素在鼠标上经过的事件(事件委托)
tabControlEl.onmouseover = function (event) {
// 2.1 确定发生鼠标经过的元素
var itemEl = event.target
if (!itemEl.classList.contains("item")) return
// 2.2 移除之前的active
activeEl.classList.remove("active")
// 2.3 将active添加到鼠标经过的元素
itemEl.classList.add("active")
// 2.4 让activeEl指向最新的元素
activeEl = itemEl
}16. 登录框

Click me to view the code html
html
<div class="box">
<h1 class="title">登录页面</h1>
<!-- 提示文本 -->
<div class="error hidden">
<i class="err-icon"></i>
<span class="err-msg">用户名或密码不能为空</span>
</div>
<!-- 用户名 -->
<div class="user-item">
<label for="username" class="user-icon"></label>
<input id="username" type="username" placeholder="邮箱/用户名/登录手机">
<span class="u-clear"></span>
</div>
<!-- 密码 -->
<div class="password-item">
<label for="password" class="pwd-icon"></label>
<input id="password" type="password" placeholder="密码">
<span class="eye-icon"></span>
<span class="p-clear"></span>
</div>
<!-- 登录 -->
<div class="login">登录</div>
</div>Click me to view the code css
css
html,
body,
div,
h1,
i,
span,
input {
/* 去除默认样式 */
margin: 0;
padding: 0;
}
input {
/* 去除边框 */
border: none;
/* 不要外轮廓 */
outline: none;
}
/* 布局代码 */
.box {
width: 304px;
margin: 100px auto;
text-align: center;
}
/* 1.标题 */
.box .title {
margin-bottom: 8px;
}
/* 2.提示文本 */
.box .error {
display: flex;
align-items: center;
margin-bottom: 8px;
background-color: #ffebeb;
padding: 5px 0;
color: #e4393c;
border: 1px solid #faccc6;
}
.box .error.hidden {
visibility: hidden;
}
.box .error .err-icon {
display: inline-block;
width: 16px;
height: 16px;
margin-left: 10px;
background: url(./images/css_sprites.png) no-repeat -114px -59px;
}
.box .error .err-msg {
margin-left: 10px;
font-size: 12px;
}
/* 3.用户名/密码 */
.box .user-item,
.box .password-item {
position: relative;
display: flex;
height: 38px;
margin-bottom: 8px;
border: 1px solid #bdbdbd;
}
.box .user-item .user-icon,
.box .password-item .pwd-icon {
width: 38px;
height: 38px;
background: url(./images/css_sprites.png) no-repeat -10px -10px;
border-right: 1px solid #bdbdbd;
}
.box .user-item input,
.box .password-item input {
flex: 1;
padding: 10px 0 10px 12px;
font-size: 14px;
}
.box .user-item .u-clear,
.box .password-item .p-clear {
position: absolute;
right: 6px;
top: 50%;
transform: translate(0, -50%);
width: 14px;
height: 14px;
background: url(./images/css_sprites.png) -36px -154px;
}
.box .password-item .eye-icon {
position: absolute;
right: 27px;
top: 15px;
width: 25px;
height: 15px;
background: url(./images/css_sprites.png) no-repeat -152px -18px;
}
/* 4.登录 */
.box .login {
height: 32px;
line-height: 32px;
font-size: 20px;
color: #fff;
background-color: #e4393c;
border: 1px solid #cb2a2d;
}Click me to view the code js
js
// 1.获取元素
var boxEl = document.querySelector(".box")
var errorEl = boxEl.querySelector(".error")
var uClearEl = boxEl.querySelector(".u-clear")
var pClearEl = boxEl.querySelector(".p-clear")
var usernameInputEl = boxEl.querySelector("#username")
var passwordInputEl = boxEl.querySelector("#password")
var eyeIconEl = boxEl.querySelector(".eye-icon")
var loginEl = boxEl.querySelector(".login")
// 2.监听loginEl元素的点击
loginEl.onclick = function (event) {
// 如果表单没有输入直接提示并直接返回
if (!usernameInputEl.value || !passwordInputEl.value) {
errorEl.classList.remove("hidden")
return
}
}
// 3.监听uClearEl元素的点击
uClearEl.onclick = function () {
// 清除表单内容
usernameInputEl.value = ""
}
// 4.监听pClearEl元素的点击
pClearEl.onclick = function () {
// 清除表单内容
passwordInputEl.value = ""
}
// 5.记住当前开眼/闭眼状态
var isFlag = false
// 6.监听eyeIconEl元素的点击
eyeIconEl.onclick = function () {
isFlag = !isFlag
// if (isFlag) {
// passwordInputEl.type = "text"
// this.style.backgroundPosition = "-150px -60px"
// this.style.top = "13px"
// } else {
// passwordInputEl.type = "password"
// 将值设置为空字符串,那么会使用CSS的默认样式
// this.style.backgroundPosition = ""
// }
// 等价于👆🏻注释代码
passwordInputEl.type = isFlag ? "text" : "password"
// 将值设置为空字符串,那么会使用CSS的默认样式
this.style.backgroundPosition = isFlag ? "-150px -60px" : ""
// 将值设置为空字符串,那么会使用CSS的默认样式
this.style.top = isFlag ? "13px" : ""
}17. 普通轮播图

Click me to view the code html
html
<div class="banner">
<!-- 图片数据 -->
<ul class="image-list">
<li class="item">
<a href="#">
<img src="./images/banner_01.jpeg" alt="星梦皮肤大赛">
</a>
</li>
<li class="item">
<a href="#">
<img src="./images/banner_02.jpeg" alt="全国大赛赛程">
</a>
</li>
<li class="item">
<a href="#">
<img src="./images/banner_03.jpeg" alt="K甲夏季赛赛程">
</a>
</li>
<li class="item">
<a href="#">
<img src="./images/banner_04.jpeg" alt="全民单挑赛招募">
</a>
</li>
<li class="item">
<a href="#">
<img src="./images/banner_05.jpeg" alt="王者萌萌假日">
</a>
</li>
</ul>
<!-- 列表数据 -->
<ul class="title-list">
<li class="item active">
<a href="#">星梦皮肤大赛</a>
</li>
<li class="item">
<a href="#">全国大赛赛程</a>
</li>
<li class="item">
<a href="#">K甲夏季赛赛程</a>
</li>
<li class="item">
<a href="#">全民单挑赛招募</a>
</li>
<li class="item">
<a href="#">王者萌萌假日</a>
</li>
</ul>
</div>Click me to view the code css
css
/* 样式重置 */
html,
body,
div,
ul,
li,
a,
img {
/* 去除默认样式 */
margin: 0;
padding: 0;
}
ul,
li {
/* 去除小圆点 */
list-style: none;
}
a {
/* 不要下划线 */
text-decoration: none;
/* 不要外轮廓 */
outline: none;
}
img {
vertical-align: top;
}
/* 布局代码 */
.banner {
width: 604px;
margin: 100px auto;
/* 超出隐藏 */
overflow: hidden;
}
/* 1.图片数据 */
.banner .image-list {
display: flex;
}
.banner .image-list .item {
flex-shrink: 0;
}
.banner .image-list .item a {
display: inline-block;
}
.banner .image-list .item a img {
width: 100%;
height: 100%;
}
/* 2.标题数据 */
.banner .title-list {
display: flex;
}
.banner .title-list .item {
flex: 1;
height: 44px;
line-height: 44px;
text-align: center;
background-color: #000;
}
.banner .title-list .item a {
display: block;
font-size: 14px;
color: #b1b2be;
}
.banner .title-list .item.active a {
color: #f3c258;
}Click me to view the code js
js
// 1.获取元素
var bannerEl = document.querySelector(".banner")
var imageListEl = bannerEl.querySelector(".image-list")
var titleListEl = bannerEl.querySelector(".title-list")
// 2.记录一些常见的变量
var currentIndex = 0 // 当前索引
var activeEl = titleListEl.querySelector(".active") // 选中的标题
var timeID = null // 定时器
// 3.自动轮播
startTime()
// 4.鼠标经过titleEl元素
titleListEl.onmouseover = function (event) {
// 4.1 获取itemEl元素
var itemEl = event.target.parentElement
if (!itemEl.classList.contains("item")) return
// 4.2 鼠标经过itemEl元素显示对应索引的图片
// 获取索引
var index = Array.from(this.children).findIndex(function (item) {
return item === itemEl
})
// 记录最新的索引
currentIndex = index
// 切换轮播图
switchBanner()
}
// 5.鼠标经过banner元素,停止定时器
bannerEl.onmouseenter = function () {
clearInterval(timeID)
}
// 6.鼠标离开bannerEl元素时,开启定时器
bannerEl.onmouseleave = function() {
startTime()
}
// 5.切换轮播图
function switchBanner() {
// 自动轮播图片
imageListEl.style.transform = `translate(${-currentIndex * 604}px, 0)`;
imageListEl.style.transition = `all .3s ease`
// 4.3 鼠标经过itemEl元素显示对应索引的标题
// 移除之前的active
activeEl.classList.remove("active")
// 添加active
var itemEl = titleListEl.children[currentIndex]
itemEl.classList.add("active")
// 记住最新的active
activeEl = itemEl
}
// 6.定时器
function startTime() {
timeID = setInterval(function () {
currentIndex++
if (currentIndex === imageListEl.children.length) currentIndex = 0
// 切换轮播图
switchBanner()
}, 3000)
}18. 定位轮播图

Click me to view the code css
css
/* 图片数据 */
.banner .image-list {
position: relative;
height: 298px;
overflow: hidden;
}
.banner .image-list .item {
position: absolute;
left: 100%;
width: 100%;
}
.banner .image-list .item:first-child {
left: 0;
}Click me to view the code js
js
// 1.获取元素
var bannerEl = document.querySelector(".banner")
var imageListEl = bannerEl.querySelector(".image-list")
var titleListEl = bannerEl.querySelector(".title-list")
// 2.定义一些常见的变量
var activeEl = titleListEl.querySelector(".active") // 选中标题
var currentIndex = 0 // 当前索引
var previousIndex = 0 // 上一个索引
var timeID = null // 定时器
// 3.自动轮播
startTimer()
// 4.鼠标经过titleListEl元素
titleListEl.onmouseover = function (event) {
var itemEl = event.target.parentElement
if (!itemEl.classList.contains("item")) return
// 获取索引
var index = Array.from(this.children).findIndex(function (item) {
return itemEl === item
})
currentIndex = index
// 切换轮播图
switchBanner()
}
// 5.鼠标经过banner元素,停止定时器
bannerEl.onmouseenter = function () {
clearInterval(timeID)
}
bannerEl.onmouseleave = function() {
startTimer()
}
// 切换轮播图
function switchBanner() {
// 3.2 图片自动轮播
for (var i = 0; i < imageListEl.children.length; i++) {
var itemEl = imageListEl.children[i]
// currentIndex 和 previousIndex 有动画
if (i === currentIndex) {
itemEl.style.left = "0"
itemEl.style.transition = "left 300ms ease"
} else if (i > currentIndex) {
if (i !== previousIndex) {
itemEl.style.transition = "none"
}
itemEl.style.left = "100%"
} else {
if (i !== previousIndex) {
itemEl.style.transition = "none"
}
itemEl.style.left = "-100%"
}
}
// 3.3 标题自动轮播
// 移除之前的active
activeEl.classList.remove("active")
// 添加active
var currentItemEl = titleListEl.children[currentIndex]
currentItemEl.classList.add("active")
// 记录最新的activeEl
activeEl = currentItemEl
}
// 定时器
function startTimer() {
timeID = setInterval(function () {
// 3.1 记住最新的上一个索引
previousIndex = currentIndex
currentIndex++
if (currentIndex === imageListEl.children.length) currentIndex = 0
// 切换轮播图
switchBanner()
}, 3000)
}19. 书籍购物车

Click me to view the code html
html
<table>
<thead>
<th>编号</th>
<th>书籍名词</th>
<th>出版日期</th>
<th>价格</th>
<th>购买数量</th>
<th>操作</th>
</thead>
<tbody></tbody>
</table>
<h2 class="price">总价格: ¥<span class="price-count">0</span></h2>Click me to view the code css
css
table {
/* 合并边框 */
border-collapse: collapse;
}
th,
td {
padding: 5px 20px;
text-align: center;
border: 1px solid #000;
}Click me to view the code js
js
var books = [
{
id: 1,
name: '《算法导论》',
date: '2006-09',
price: 85.00,
count: 3
},
{
id: 2,
name: '《UNIX编程艺术》',
date: '2006-02',
price: 59.00,
count: 2
},
{
id: 3,
name: '《编程珠玑》',
date: '2008-10',
price: 39.00,
count: 5
},
{
id: 4,
name: '《代码大全》',
date: '2006-03',
price: 128.00,
count: 8
}
]
// 1.获取元素
var tbodyEl = document.querySelector("tbody")
var priceEl = document.querySelector(".price-count")
// 2.循环动态创建表格
for (var i = 0; i < books.length; i++) {
// 2.1 创建tr元素
var rowEl = document.createElement("tr")
var book = books[i] // {...}
for (var j in book) {
// 创建td元素
var cellEl = document.createElement("td")
var value = book[j]
if (j === "price") {
value = "¥" + value
}
// 设置td元素内容
cellEl.textContent = value
// 插入到tr中
rowEl.append(cellEl)
}
// 创建删除按钮的td元素
var deleteCell = document.createElement("td")
// 创建删除按钮的button元素
var deleteEl = document.createElement("button")
// 设置删除按钮的内容
deleteEl.textContent = "删除"
// 删除按钮button插入删除按钮的td
deleteCell.append(deleteEl)
// 删除按钮的td插入到tr
rowEl.append(deleteCell)
// 监听删除按钮的点击
deleteEl.onclick = function (event) {
// 当前行
var currentCell = event.target.parentElement.parentElement
// 当前行的索引
var currentIndex = currentCell.sectionRowIndex
// 删除tr
currentCell.remove()
// 删除books中的数据
books.splice(currentIndex, 1)
// 重新计算总价格
totalPrice()
}
// 计算总价格
totalPrice()
// 定义计算总价格函数
function totalPrice() {
var total = 0
// 计算总和方法:
// 🚚 for 循环
// for (var i = 0; i < books.length; i++) {
// total += books[i].price * books[i].count
// }
// ✈️ arr.reduce
total = books.reduce(function(preValue, item) {
return preValue + item.price * item.count
}, 0)
priceEl.textContent = total
}
// 2. 插入到tbodyEl中
tbodyEl.append(rowEl)
}20. 商品过滤的算法

Click me to view the code js
js
var infos = [
{ name: "ccb", friends: ["abc", "cba"] },
{ name: "kobe", friends: ["nba", "cba"] },
{ name: "james", friends: ["nba", "cba", "abc"] }
]
var filters = ["abc", "cba"]
var filterInfos = infos.filter(function(item) {
var isFlag = true
var friends = item.friends
for (var filterItemEl of filters) {
if (!friends.includes(filterItemEl)) {
isFlag = false
break
}
}
return isFlag
})
console.log(filterInfos)21. 颜色过滤的算法

Click me to view the code html
html
<div class="box">
<button>red</button>
<button>yellow</button>
<button>blue</button>
</div>
<ul></ul>Click me to view the code css
css
.box button {
/* 鼠标小手 */
cursor: pointer;
}
.box button.active {
color: #f00;
}Click me to view the code js
js
// 1.默认大量的数据
var students = [
{ name: "小明", colors: ["red", "blue", "green"] },
{ name: "小王", colors: ["orange", "yellow", "red"] },
{ name: "小龙", colors: ["purple", "yellow", "black"] },
{ name: "小李", colors: ["red", "orange", "blue"] }
]
// 2.点击按钮,按钮变成选中状态
var boxEl = document.querySelector(".box")
// 3.定义变量
var filters = [] // 记录用户选中的颜色
var filterStudents = students // 筛选后的数据
// 4.点击按钮慢变成选中状态
boxEl.onclick = function (event) {
if (event.target === this) return
// 切换active
event.target.classList.toggle("active")
// 修改filters
if (event.target.classList.contains("active")) {
filters.push(event.target.textContent.trim())
} else {
var filterItem = event.target.textContent.trim()
var index = filters.findIndex(function (item) {
return item === filterItem
})
filters.splice(index, 1)
}
// 过滤数据
filterStudentsAction()
}
// 封装函数: 过滤数据
function filterStudentsAction() {
// ✈️ 方法一: filter
// filterStudents = students.filter(function (item) {
// var isFlag = true
// var colors = item.colors
// for (var itemEl of filters) {
// if (!colors.includes(itemEl)) {
// isFlag = false
// break
// }
// }
// return isFlag
// })
// 🚚 方法二: for...of
filterStudents = []
for (var stu of students) {
var colors = stu.colors
var isFlag = true
for (var itemEl of filters) {
if (!colors.includes(itemEl)) {
isFlag = false
break
}
}
if (isFlag === true) {
filterStudents.push(stu)
}
}
// 展示数据
showStudentsAction()
}
// 封装函数: 展示数据
var ulEl = document.querySelector("ul")
showStudentsAction()
function showStudentsAction() {
ulEl.innerHTML = ""
for (var i = 0; i < filterStudents.length; i++) {
var liEl = document.createElement("li")
liEl.textContent = filterStudents[i].name
ulEl.append(liEl)
}
}22. 华为商城的商品过滤

1. 界面搭建
Click me to view the code html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 样式重置 -->
<link rel="stylesheet" href="./css/rest.css">
<!-- 公共样式 -->
<link rel="stylesheet" href="./css/common.css">
<!-- 商品列表 -->
<link rel="stylesheet" href="./css/product.css">
</head>
<body>
<!-- 版心 -->
<div class="wrapper">
<!-- crumbs 面包屑(导航) -->
<div class="crumbs">
<span class="item">首页</span>
<span>></span>
<span class="item">笔记本</span>
</div>
<!-- 对内容进行操作(operation) -->
<div class="operation">
<!-- 分类 -->
<ul class="row category">
<li class="item">分类 :</li>
<li class="item active">笔记本</li>
<li class="item">MateBook E系列</li>
<li class="item">MateBook D系列</li>
<li class="item">MateBook X系列</li>
<li class="item">华为显示器系列</li>
<li class="item">MateBook B系列</li>
<li class="item nowrap_ellipsis">MateBook数字系列</li>
</ul>
<!-- 优惠 -->
<ul class="row discount">
<li class="item">服务优惠 :</li>
<li class="item">仅看有货</li>
<li class="item">分期免息</li>
<li class="item">优惠商品</li>
</ul>
<!-- 排序 -->
<ul class="row sort">
<li class="item">排序 :</li>
<li class="item active">综合</li>
<li class="item">最新</li>
<li class="item">评论数</li>
<li class="item">价格</li>
</ul>
</div>
<!-- 商品列表部分 -->
<ul class="products">
<li class="item">
<a href="#">
<!-- 封面 -->
<img class="album" src="./img/product_01.webp" alt="">
<!-- 名字 -->
<div class="name">
<i class="new">新品</i>
<span class="title nowrap_ellipsis">HUAWEI MateBook 16s 2023</span>
</div>
<!-- 描述 -->
<div class="describe nowrap_ellipsis">2.5K高色准触控屏,13代酷睿处理器</div>
<!-- 服务 -->
<div class="service">
<span class="tip">至高省200元 13代酷睿</span>
</div>
<!-- 价格 -->
<div class="price">
<span class="new-price">¥9999</span>
</div>
<!-- 评论 -->
<div class="comment">
<span>163人评价</span>
<span>95%好评</span>
</div>
</a>
</li>
<li class="item">
<a href="#">
<!-- 封面 -->
<img class="album" src="./img/product_02.webp" alt="">
<!-- 名字 -->
<div class="name">
<i class="new">新品</i>
<span class="title nowrap_ellipsis">HUAWEI MateBook 16s 2023</span>
</div>
<!-- 描述 -->
<div class="describe nowrap_ellipsis">2K触控全面屏,13代酷睿处理器,超级终端</div>
<!-- 服务 -->
<div class="service">
<span class="tip">新品至高省200元 13代酷睿</span>
</div>
<!-- 价格 -->
<div class="price">
<span class="new-price">¥5799</span>
<span class="old-price">¥5999</span>
</div>
<!-- 评论 -->
<div class="comment">
<span>225人评价</span>
<span>98%好评</span>
</div>
</a>
</li>
<li class="item">
<a href="#">
<!-- 封面 -->
<img class="album" src="./img/product_03.webp" alt="">
<!-- 名字 -->
<div class="name">
<i class="new">新品</i>
<span class="title nowrap_ellipsis">HUAWEI MateBook X Pro 2023</span>
</div>
<!-- 描述 -->
<div class="describe nowrap_ellipsis">微绒/金属机身,3.1K原色全面屏,至高32G+2TB</div>
<!-- 服务 -->
<div class="service">
<span class="tip">至高立省1400元</span>
</div>
<!-- 价格 -->
<div class="price">
<span class="new-price">¥13999</span>
</div>
<!-- 评论 -->
<div class="comment">
<span>167人评价</span>
<span>96%好评</span>
</div>
</a>
</li>
<li class="item">
<a href="#">
<!-- 封面 -->
<img class="album" src="./img/product_04.webp" alt="">
<!-- 名字 -->
<div class="name">
<i class="new">新品</i>
<span class="title nowrap_ellipsis">HUAWEI MateBook E 2023款</span>
</div>
<!-- 描述 -->
<div class="describe nowrap_ellipsis">二合一笔记本丨120Hz OLED原色屏</div>
<!-- 服务 -->
<div class="service">
<span class="tip">限时降100 | 12期0分期利息</span>
</div>
<!-- 价格 -->
<div class="price">
<span class="new-price">¥7399</span>
<span class="old-price">¥7499</span>
</div>
<!-- 评论 -->
<div class="comment">
<span>298人评价</span>
<span>98%好评</span>
</div>
</a>
</li>
<li class="item">
<a href="#">
<!-- 封面 -->
<img class="album" src="./img/product_05.webp" alt="">
<!-- 名字 -->
<div class="name">
<span class="title nowrap_ellipsis">HUAWEI MateBook D 14 系列</span>
</div>
<!-- 服务 -->
<div class="service">
<span class="tip">限时直降100元</span>
<span class="tip">增积分</span>
</div>
<!-- 价格 -->
<div class="price">
<span class="new-price">¥4599</span>
<span class="old-price">¥4699</span>
</div>
<!-- 评论 -->
<div class="comment">
<span>7人评价</span>
<span>86%好评</span>
</div>
</a>
</li>
<li class="item">
<a href="#">
<!-- 封面 -->
<img class="album" src="./img/product_06.webp" alt="">
<!-- 名字 -->
<div class="name">
<i class="new">价保618</i>
<span class="title nowrap_ellipsis">HUAWEI MateBook D 16</span>
</div>
<!-- 描述 -->
<div class="describe nowrap_ellipsis">16''护眼全面屏,13代酷睿标压处理器,超级终端</div>
<!-- 服务 -->
<div class="service">
<span class="tip">限时直降600元</span>
<span class="tip">3期0分期利息</span>
<span class="tip">赠积分</span>
</div>
<!-- 价格 -->
<div class="price">
<span class="new-price">¥4999</span>
<span class="old-price">¥5599</span>
</div>
<!-- 评论 -->
<div class="comment">
<span>4437人评价</span>
<span>94%好评</span>
</div>
</a>
</li>
<li class="item">
<a href="#">
<!-- 封面 -->
<img class="album" src="./img/product_07.webp" alt="">
<!-- 名字 -->
<div class="name">
<i class="new">新品</i>
<span class="title nowrap_ellipsis">HUAWEI MateBook 16s 2023</span>
</div>
<!-- 描述 -->
<div class="describe nowrap_ellipsis">2.5K高色准触控屏,13代酷睿处理器</div>
<!-- 服务 -->
<div class="service">
<span class="tip">至高省200元 13代酷睿</span>
</div>
<!-- 价格 -->
<div class="price">
<span class="new-price">¥9999</span>
</div>
<!-- 评论 -->
<div class="comment">
<span>163人评价</span>
<span>95%好评</span>
</div>
</a>
</li>
<li class="item">
<a href="#">
<!-- 封面 -->
<img class="album" src="./img/product_08.webp" alt="">
<!-- 名字 -->
<div class="name">
<i class="new">新品</i>
<span class="title nowrap_ellipsis">HUAWEI MateBook 16s 2023</span>
</div>
<!-- 描述 -->
<div class="describe nowrap_ellipsis">2K触控全面屏,13代酷睿处理器,超级终端</div>
<!-- 服务 -->
<div class="service">
<span class="tip">新品至高省200元 13代酷睿</span>
</div>
<!-- 价格 -->
<div class="price">
<span class="new-price">¥5799</span>
<span class="old-price">¥5999</span>
</div>
<!-- 评论 -->
<div class="comment">
<span>225人评价</span>
<span>98%好评</span>
</div>
</a>
</li>
</ul>
</div>
</body>
</html>Click me to view the code css
css
/* 这里存放的是样式重置 */
body,div,ul,li,a,img,i {
/* 去除默认样式 */
padding: 0;
margin: 0;
}
ul,li {
/* 去除小圆点 */
list-style: none;
}
a {
/* 去除下划线 */
text-decoration: none;
color: #333;
}
img {
vertical-align: top;
}
i {
font-style: normal;
}Click me to view the code css
css
/* 这里存放的是公共样式 */
body {
background-color: rgb(241, 243, 245);
}
/* 版心 */
.wrapper {
width: 1200px;
margin: 0 auto;
}
.nowrap_ellipsis {
/* 🚚 单行文本显示省略号 */
/* 1.文本不换行显示 */
white-space: nowrap;
/* 2.文本超出隐藏 */
overflow: hidden;
/* 3.文本超出显示省略号 */
text-overflow: ellipsis;
}Click me to view the code css
css
/* 这里存放的是商品列表 */
/* crumbs 面包屑(导航) */
.crumbs {
display: flex;
height: 63px;
margin-top: 100px;
line-height: 63px;
font-size: 12px;
color: #000;
}
.crumbs .item {
/* 鼠标小手 */
cursor: pointer;
}
.crumbs .item:last-child {
font-weight: 700;
}
/* > */
.crumbs span:not(.item) {
padding: 0 2px;
}
/* 操作 */
.operation {
padding: 0 24px;
background-color: #fff;
}
.operation>.row {
display: flex;
}
.operation>.row .item {
width: 104px;
height: 48px;
box-sizing: border-box;
margin: 0 8px;
padding: 0 4px;
line-height: 48px;
font-size: 12px;
color: #000;
/* 鼠标小手 */
cursor: pointer;
}
.operation>.row .item:first-child {
color: #333;
/* 透明度 */
opacity: 0.6;
/* 默认不要鼠标小手 */
cursor: auto;
}
.operation>.row .item.active {
color: #cf0a2c;
}
/* 商品列表 */
.products {
display: flex;
/* 换行 */
flex-wrap: wrap;
/* 水平方向两端对齐 */
justify-content: space-between;
margin-top: 24px;
}
.products>.item {
width: 291px;
margin-bottom: 12px;
background-color: #fff;
}
.products>.item:hover {
box-shadow: rgba(0, 0, 0, .1) 0 0 36px;
}
.products>.item a {
/* display: block; */
/* 🔥 图片水平居中对齐 */
/* 🚚 方法一 */
/* text-align: center; */
/* 🚚 方法二 */
display: flex;
/* 改变主轴方向 */
flex-direction: column;
/* 水平方向居中对齐 */
align-items: center;
}
/* 封面 */
.products>.item .album {
width: 180px;
height: 180px;
margin: 30px 0;
}
/* 名字 */
.products>.item .name {
display: flex;
align-items: center;
height: 19px;
color: #000;
}
.products>.item .name .new {
height: 16px;
margin-right: 4px;
padding: 0 4px;
line-height: 16px;
font-size: 12px;
color: #fff;
background-color: #fa3040;
border-radius: 4px;
}
.products>.item .name .title {
width: 211px;
}
/* 描述 */
.products>.item .describe {
width: 243px;
height: 18px;
margin-top: 4px;
text-align: center;
line-height: 18px;
font-size: 13px;
color: #000;
opacity: 0.5;
}
/* 价格 */
.products>.item .price {
display: flex;
justify-content: center;
align-items: center;
margin-top: 12px;
font-weight: 700;
color: #000;
}
.products>.item .price .old-price {
margin-left: 4px;
font-size: 12px;
font-weight: 400;
opacity: 0.4;
/* 删除线 */
text-decoration: line-through;
}
/* 服务 */
.products>.item .service {
display: flex;
justify-content: center;
margin-top: 8px;
}
.products>.item .service .tip {
margin-right: 4px;
padding: 0 4px;
font-size: 12px;
color: #000;
border: 1px solid rgba(0, 0, 0, 0.4);
border-radius: 4px;
}
.products>.item .service .tip:first-child {
color: #cf0a2c;
border-color: #e2002466;
}
/* 评论 */
.products>.item .comment {
display: flex;
margin: 8px 0 19px;
opacity: 0.5;
font-size: 12px;
}
.products>.item .comment span:first-child {
margin-right: 8px;
}2. 动态展示数据
Click me to view the code html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 样式重置 -->
<link rel="stylesheet" href="./css/rest.css">
<!-- 公共样式 -->
<link rel="stylesheet" href="./css/common.css">
<!-- 商品列表 -->
<link rel="stylesheet" href="./css/product.css">
</head>
<body>
<!-- 版心 -->
<div class="wrapper">
<!-- crumbs 面包屑(导航) -->
<div class="crumbs">
<span class="item">首页</span>
<span>></span>
<span class="item">笔记本</span>
</div>
<!-- 对内容进行操作(operation) -->
<div class="operation">
<!-- 分类 -->
<ul class="row category">
<li class="item">分类 :</li>
<li class="item active">笔记本</li>
<li class="item">MateBook E系列</li>
<li class="item">MateBook D系列</li>
<li class="item">MateBook X系列</li>
<li class="item">华为显示器系列</li>
<li class="item">MateBook B系列</li>
<li class="item nowrap_ellipsis">MateBook数字系列</li>
</ul>
<!-- 优惠 -->
<ul class="row discount">
<li class="item">服务优惠 :</li>
<li class="item">仅看有货</li>
<li class="item">分期免息</li>
<li class="item">优惠商品</li>
</ul>
<!-- 排序 -->
<ul class="row sort">
<li class="item">排序 :</li>
<li class="item active">综合</li>
<li class="item">最新</li>
<li class="item">评论数</li>
<li class="item">价格</li>
</ul>
</div>
<!-- 商品列表部分 -->
<ul class="products"></ul>
</div>
</body>
</html>Click me to view the code js
js
// product_data.js
var resultList = [
{
"briefName": "HUAWEI MateBook E 12.6英寸",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "96",
"isInv": 1,
"mobileVideoPath": "",
"name": "HUAWEI MateBook E 12.6英寸",
"tag": "价保618",
"photoName": "3007F35C1B59029E58A4AE3098AC7E02mp.jpg",
"photoPath": "/uomcdn/CN/pms/202112/displayProduct/10086765396129/",
"picture3DPath": "",
"price": {
"newPrice": 6499,
"oldPrice": 6599
},
"priceAccurate": 6499,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086765396129,
"promoLabels": [
"分期免息",
"赠送积分"
],
"promotionInfo": "预订立省300元|12期免息",
"rateCount": 3190,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "2801010088403",
"skuCount": 6,
"skuName": "【磁吸键盘套装】HUAWEI MateBook E 2022款二合一笔记本 11代酷睿 i5 16G 512G Win11 12.6英寸 OLED原色全面屏 多设备互联 星际蓝",
"webVideoPath": "",
"services": [
"仅看有货",
"分期免息",
"优惠商品"
]
},
{
"briefName": "HUAWEI MateBook 14s",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayTags": "热销爆款",
"displayToCustomer": "0",
"goodRate": "95",
"isInv": 1,
"mobileVideoPath": "https://vod.vmall.com/asset/bbe93206e5d086880f87f994c57428b9/play_video/f7de0a3ad7021d22ad70161c8f3e1d11_2.mp4",
"name": "HUAWEI MateBook 14s",
"tag": "价保618",
"photoName": "E57FFE1FF4B1FE19D48F93E3D98439BDmp.jpg",
"photoPath": "/uomcdn/CN/pms/202112/displayProduct/10086088858159/",
"picture3DPath": "",
"price": {
"newPrice": 6699,
"oldPrice": 6999
},
"priceAccurate": 6699,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086088858159,
"promoLabels": [
"分期免息",
"赠送积分"
],
"promotionInfo": "预订立省400元",
"rateCount": 3327,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "2801010080208",
"skuCount": 6,
"skuName": "HUAWEI MateBook 14s 14.2英寸 11代酷睿标压处理器 i5 16GB 512GB 2.5K触控全面屏 90Hz高刷 锐炬显卡 乐享App 多设备互联 轻薄笔记本 云杉绿",
"tagBgColor": "FF6A6E",
"webVideoPath": "https://vod.vmall.com/asset/bbe93206e5d086880f87f994c57428b9/play_video/f7de0a3ad7021d22ad70161c8f3e1d11_2.mp4",
"services": [
"仅看有货",
"优惠商品"
]
},
{
"briefName": "HUAWEI PixLab X1 黑白激光打印机",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "96",
"isInv": 1,
"mobileVideoPath": "https://vod.vmall.com/asset/9c044103e5c783bd17323e53a643ed3c/play_video/a94107f5055c8297dcefbfa9a02a3ca0_2.mp4",
"name": "HUAWEI PixLab X1 黑白激光打印机",
"tag": "新品",
"photoName": "D1BA03B40ACBDE152A51E93ACE23DA9A227EE48AB3606C39mp.png",
"photoPath": "/product/6941487237746/",
"picture3DPath": "",
"price": {
"newPrice": 1899,
"oldPrice": 1999
},
"priceAccurate": 1899,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086478166035,
"promoLabels": [
"分期免息",
"赠送积分"
],
"promotionInfo": "预订立省400元",
"rateCount": 2734,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "3102150348801",
"skuCount": 1,
"skuName": "【新品】华为黑白激光多功能打印机 HUAWEI PixLab X1 HarmonyOS 靠近配网 一碰打印 复印扫描",
"webVideoPath": "https://vod.vmall.com/asset/9c044103e5c783bd17323e53a643ed3c/play_video/a94107f5055c8297dcefbfa9a02a3ca0_2.mp4",
"services": [
"分期免息",
"优惠商品"
]
},
{
"briefName": "HUAWEI MateBook 14 2021款",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "94",
"isInv": 1,
"mobileVideoPath": "https://vod.vmall.com/asset/5a78d2cbfc1e8bfa0b89d1bdf7847e8d/play_video/82d48481f2da3f9cf71f86152a21c398_2.mp4",
"name": "HUAWEI MateBook 14 2021款",
"tag": "新品",
"photoName": "0586DDD43A796BB8F9DCE0CF38A3C248212C18CA891A2AB9mp.png",
"photoPath": "/product/6941487210565/",
"picture3DPath": "",
"price": {
"newPrice": 5699,
"oldPrice": 6999
},
"priceAccurate": 5699,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086549931177,
"promoLabels": [
"分期免息",
"赠送积分"
],
"promotionInfo": "预订最高省400元",
"rateCount": 4163,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "2801010061733",
"skuCount": 7,
"skuName": "HUAWEI MateBook 14 2021款 i5 16GB 512GB(深空灰)锐炬显卡 触控屏 11代酷睿处理器 14英寸2K护眼全面屏轻薄笔记本",
"webVideoPath": "https://vod.vmall.com/asset/5a78d2cbfc1e8bfa0b89d1bdf7847e8d/play_video/82d48481f2da3f9cf71f86152a21c398_2.mp4",
"services": [
"仅看有货",
"分期免息",
"优惠商品"
]
},
{
"briefName": "HUAWEI MateBook X Pro 2021款",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "97",
"isInv": 1,
"mobileVideoPath": "https://vod.vmall.com/asset/f3cdc6af7392602c47d4d5c49a87af12/play_video/bdcee2ce27b4f25888281d54e05738a7_2.mp4",
"name": "HUAWEI MateBook X Pro 2021款",
"photoName": "C3B4EDC1CBDB58C859ED06B23B852CD1mp.jpg",
"photoPath": "/uomcdn/CN/pms/202112/displayProduct/10086857314109/",
"picture3DPath": "",
"price": {
"newPrice": 10999,
"oldPrice": 12999
},
"priceAccurate": 10999,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086857314109,
"promoLabels": [
"分期免息",
"赠送积分"
],
"promotionInfo": "尊享12期免息",
"rateCount": 6029,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "2801010057233",
"skuCount": 3,
"skuName": "HUAWEI MateBook X Pro 2021款 i7 16GB 1TB(深空灰)锐炬显卡 13.9英寸3K高清触控屏 11代酷睿处理器 商务轻薄笔记本",
"webVideoPath": "https://vod.vmall.com/asset/f3cdc6af7392602c47d4d5c49a87af12/play_video/bdcee2ce27b4f25888281d54e05738a7_2.mp4",
"services": [
"仅看有货",
"优惠商品"
]
},
{
"briefName": "HUAWEI MateBook 13 2021款",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "95",
"isInv": 1,
"mobileVideoPath": "https://vod.vmall.com/asset/fb588aa94c2eb9bad7ef80ea909927d7/play_video/0ce23ff7d645e17774dc59b1a4d0d561_2.mp4",
"name": "HUAWEI MateBook 13 2021款",
"tag": "价保618",
"photoName": "3DABF5539F6B25DF426191D94B8D8415FAA73E1C8681C940mp.png",
"photoPath": "/product/6941487236411/",
"picture3DPath": "",
"price": {
"newPrice": 5199
},
"priceAccurate": 5199,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086294084142,
"promoLabels": [
"分期免息",
"赠送积分"
],
"promotionInfo": "预订立省200元",
"rateCount": 2297,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "2801010059937",
"skuCount": 6,
"skuName": "HUAWEI MateBook 13 2021款 i5 16GB 512GB(银)2K炫丽全面屏 11代酷睿处理器13英寸轻薄笔记本",
"webVideoPath": "https://vod.vmall.com/asset/fb588aa94c2eb9bad7ef80ea909927d7/play_video/0ce23ff7d645e17774dc59b1a4d0d561_2.mp4",
"services": [
"仅看有货",
"分期免息",
]
},
{
"briefName": "HUAWEI MateBook 16",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "96",
"isInv": 1,
"mobileVideoPath": "",
"name": "HUAWEI MateBook 16",
"tag": "价保618",
"photoName": "25208B40BAF8CF246305FD1559BC09EAmp.png",
"photoPath": "/uomcdn/CN/pms/202306/displayProduct/10086049915262/",
"picture3DPath": "",
"price": {
"newPrice": 6599,
"oldPrice": 6799
},
"priceAccurate": 6599,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086475813571,
"promoLabels": [
"分期免息",
"赠送积分"
],
"promotionInfo": "预订立省300元",
"rateCount": 1503,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "2801010066607",
"skuCount": 4,
"skuName": "【新品】HUAWEI MateBook 16 R7 16GB 512GB(灰)Windows 11 16英寸2.5K专业全面屏 标压处理器 轻薄高性能笔记本",
"webVideoPath": "",
"services": [
"仅看有货",
"分期免息"
]
},
{
"briefName": "HUAWEI MateBook 14 2021款 锐龙版",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "96",
"isInv": 1,
"mobileVideoPath": "",
"name": "HUAWEI MateBook 14 2021款 锐龙版",
"tag": "价保618",
"photoName": "64810357D54DF471C801127244440EF1mp.jpg",
"photoPath": "/uomcdn/CN/pms/202112/displayProduct/10086210747193/",
"picture3DPath": "",
"price": {
"newPrice": 6299
},
"priceAccurate": 6299,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086210747193,
"promoLabels": [
"限时特价",
"分期免息",
"赠送积分"
],
"promoPrice": 5599,
"promoPriceAccurate": 5599,
"promotionInfo": "预订立省700元",
"rateCount": 1011,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "2801010086204",
"skuCount": 4,
"skuName": "【新品】HUAWEI MateBook 14 2021 锐龙版 R7 16G 512G(深空灰)2K触控全面屏 14英寸轻薄本",
"webVideoPath": "",
"services": [
"仅看有货",
"分期免息"
]
},
{
"briefName": "HUAWEI MateBook 13s",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "94",
"isInv": 1,
"mobileVideoPath": "https://vod.vmall.com/asset/bbe93206e5d086880f87f994c57428b9/play_video/f7de0a3ad7021d22ad70161c8f3e1d11_2.mp4",
"name": "HUAWEI MateBook 13s",
"tag": "新品",
"photoName": "489E4F53219E6909E7A7F49FABA605D6C60C0B53F1DA152Amp.png",
"photoPath": "/product/6941487233809/",
"picture3DPath": "",
"price": {
"newPrice": 6499,
"oldPrice": 6699
},
"priceAccurate": 6499,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086845419415,
"promoLabels": [
"分期免息",
"赠送积分"
],
"promotionInfo": "预订立省500元",
"rateCount": 1228,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "2801010079901",
"skuCount": 4,
"skuName": "【新品】HUAWEI MateBook 13s 13.4英寸 11代酷睿标压处理器 i5 16G 512G 2.5K触控全面屏 90Hz高刷 锐炬显卡 乐享App 多设备互联 轻薄笔记本 皓月银",
"webVideoPath": "https://vod.vmall.com/asset/bbe93206e5d086880f87f994c57428b9/play_video/f7de0a3ad7021d22ad70161c8f3e1d11_2.mp4",
"services": [
"分期免息",
"优惠商品"
]
},
{
"briefName": "HUAWEI Matebook X 2021款",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "93",
"isInv": 1,
"mobileVideoPath": "https://vod.vmall.com/asset/97058dcb06ffb0e4bb545a295b6b96c7/play_video/f3c2ece4fef62a1fa88c3d39e42ee616_2.mp4",
"name": "HUAWEI Matebook X 2021款",
"tag": "价保618",
"photoName": "6E52FE5AD52A2106A11D6D894FCB12F04E037A1519BF7E05mp.png",
"photoPath": "/product/6941487215461/",
"picture3DPath": "",
"price": {
"newPrice": 6999,
},
"priceAccurate": 6999,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086715572678,
"promoLabels": [
"分期免息",
"赠送积分"
],
"promotionInfo": "预订立省200元",
"rateCount": 190,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "2801010083804",
"skuCount": 6,
"skuName": "【新品】HUAWEI MateBook X 2021款13英寸 11代酷睿 i5 16GB 512GB(冰霜银)3K触控全面屏 轻至1kg 多屏协同 4扬声器环绕音效 轻薄笔记本",
"webVideoPath": "https://vod.vmall.com/asset/97058dcb06ffb0e4bb545a295b6b96c7/play_video/f3c2ece4fef62a1fa88c3d39e42ee616_2.mp4",
"services": [
"仅看有货",
"优惠商品"
]
},
{
"briefName": "HUAWEI MateView",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "97",
"isInv": 1,
"mobileVideoPath": "",
"name": "HUAWEI MateView",
"tag": "新品",
"photoName": "83863676E551FCB7E3FBF673B61B8979EF4A923BA06F4475mp.png",
"photoPath": "/product/6941487222872/",
"picture3DPath": "",
"price": {
"newPrice": 3999,
},
"priceAccurate": 3999,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086690832694,
"promoLabels": [
"分期免息",
"赠送积分"
],
"promotionInfo": "预订立省200元",
"rateCount": 1210,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "34020000502",
"skuCount": 2,
"skuName": "【无线投屏版】HUAWEI MateView 28.2英寸 原色显示器 4K+ 超高清分辨率 电影级色域 94%高屏占比 3:2 屏幕比例 支持华为手机一碰投屏 65W Type-C反向充电",
"webVideoPath": "",
"services": [
"仅看有货",
"分期免息",
"优惠商品"
]
},
{
"briefName": "HUAWEI MateView GT 27英寸",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "96",
"isInv": 1,
"mobileVideoPath": "https://vod.vmall.com/asset/12defa62ac19c232e27eb7d33ad632e7/play_video/25081b882872f4c5a78e79a21e673704_2.mp4",
"name": "HUAWEI MateView GT 27英寸",
"photoName": "91B768F89D6CBB0B25384A645603CBD8mp.png",
"photoPath": "/uomcdn/CN/pms/202202/gbom/6941487232963/",
"picture3DPath": "",
"price": {
"newPrice": 2099,
"oldPrice": 2299
},
"priceAccurate": 2099,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086419944776,
"promoLabels": [
"分期免息",
"赠送积分"
],
"promotionInfo": "预订最高省500元",
"rateCount": 561,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "4602010001501",
"skuCount": 2,
"skuName": "HUAWEI MateView GT 27英寸2K超清曲面屏 165Hz刷新率90% P3色域 低蓝光无频闪莱茵护眼认证(无HDMI线缆)",
"webVideoPath": "https://vod.vmall.com/asset/12defa62ac19c232e27eb7d33ad632e7/play_video/25081b882872f4c5a78e79a21e673704_2.mp4",
"services": [
"仅看有货",
"分期免息",
"优惠商品"
]
},
{
"briefName": "HUAWEI MateStation S 锐龙版",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "96",
"isInv": 1,
"mobileVideoPath": "",
"name": "HUAWEI MateStation S 锐龙版",
"tag": "新品",
"photoName": "F91D2C8C6DF7A0D2E50CAD4C3ACFE42Dmp.png",
"photoPath": "/uomcdn/CN/pms/202204/sbom/4601010000304/",
"picture3DPath": "",
"price": {
"newPrice": 4998
},
"priceAccurate": 4998,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086469978892,
"promoLabels": [
"分期免息",
"赠送积分"
],
"promotionInfo": "预订最高省900元",
"rateCount": 1043,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "4601010000304",
"skuCount": 4,
"skuName": "【搭配显示器套装】HUAWEI MateStation S 小机箱台式机 7nm锐龙六核R5-4600G 8GB+512GB 多设备高效协同 一键指纹开机解锁 满载28分贝智慧风冷系统 Win10三年保修+华为显示器 S24(含HDMI线)",
"webVideoPath": "",
"services": [
"仅看有货",
"分期免息",
"优惠商品"
]
},
{
"briefName": "HUAWEI MateView GT 34英寸",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "97",
"isInv": 1,
"mobileVideoPath": "https://vod.vmall.com/asset/dd43fc2a20f3ccb66571c125d306110c/play_video/7a4bb69d530e09dcab8f0d68e9fc579b_3.mp4",
"name": "HUAWEI MateView GT 34英寸",
"tag": "价保618",
"photoName": "CAA6012E4EAA262252BC8FDA4960985Bmp.png",
"photoPath": "/uomcdn/CN/pms/202202/gbom/6941487222858/",
"picture3DPath": "",
"price": {
"newPrice": 2699,
"oldPrice": 3699
},
"priceAccurate": 2699,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086632258266,
"promoLabels": [
"分期免息",
"赠送积分"
],
"promotionInfo": "预订最高省600",
"rateCount": 783,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "34020001601",
"skuCount": 2,
"skuName": "HUAWEI MateView GT 34英寸曲面显示器 3K高清分辨率 21:9 屏幕比例 165Hz电竞刷新率 电影级色域 沉浸式环绕大屏游戏显示器(无HDMI线缆)",
"webVideoPath": "https://vod.vmall.com/asset/dd43fc2a20f3ccb66571c125d306110c/play_video/7a4bb69d530e09dcab8f0d68e9fc579b_0.mp4",
"services": [
"仅看有货",
"分期免息",
"优惠商品"
]
},
{
"briefName": "HUAWEI MateStation X",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "97",
"isInv": 1,
"mobileVideoPath": "https://vod.vmall.com/asset/a04fcf17048c946079ff773fcefcdf39/play_video/a2adc8c3286e40cb1b5a7d99bbc3fe87_2.mp4",
"name": "HUAWEI MateStation X",
"tag": "价保618",
"photoName": "2CD097D65993F90E35A97E381D9209CBBADCD3750D50113Amp.png",
"photoPath": "/product/6941487244263/",
"picture3DPath": "",
"price": {
"newPrice": 9999
},
"priceAccurate": 9999,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086246464159,
"promoLabels": [
"分期免息",
"赠送积分"
],
"promotionInfo": "预订立省500元",
"rateCount": 478,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "4603010000204",
"skuCount": 5,
"skuName": "HUAWEI MateStation X一体机 28.2英寸十点触控全面屏 锐龙R5 5600H 16GB+512GB 金属机身 多设备高效协同 一键指纹开机解锁 皓月银",
"webVideoPath": "https://vod.vmall.com/asset/a04fcf17048c946079ff773fcefcdf39/play_video/a2adc8c3286e40cb1b5a7d99bbc3fe87_2.mp4",
"services": [
"仅看有货",
"分期免息",
"优惠商品"
]
},
{
"briefName": "华为显示器 S24",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "98",
"isInv": 1,
"mobileVideoPath": "https://vod.vmall.com/asset/97c05bb2c5473dd6a3ca91a7dcfd79af/play_video/756e5358ce7ef06af4bee3eab40b1a5a.mp4",
"name": "华为显示器 S24",
"tag": "价保618",
"photoName": "AA9DBAA797633A14F84309B161392F75mp_tds2.png",
"photoPath": "/uomcdn/CN/pms/202209/gbom/6941487222865/",
"picture3DPath": "",
"price": {
"newPrice": 999
},
"priceAccurate": 999,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086839196289,
"promoLabels": [
"赠送积分"
],
"promotionInfo": "预订立省230元",
"rateCount": 1869,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "34020008701",
"skuCount": 1,
"skuName": "华为显示器 S24(灰色)全面屏高清办公显示器 窄边框90%屏占比 75Hz刷新率 顺滑画面 畅爽体验",
"webVideoPath": "https://vod.vmall.com/asset/97c05bb2c5473dd6a3ca91a7dcfd79af/play_video/756e5358ce7ef06af4bee3eab40b1a5a.mp4",
"services": [
"仅看有货",
"分期免息",
"优惠商品"
]
},
{
"briefName": "HUAWEI MateBook B3-420",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "100",
"isInv": 1,
"mobileVideoPath": "",
"name": "HUAWEI MateBook B3-420",
"tag": "价保618",
"photoName": "C87F6C546FEBC02F0A3931780657D7095AEDE8CC5BE5C793mp.png",
"photoPath": "/product/6941487217120/",
"picture3DPath": "",
"price": {
"newPrice": 5199,
"oldPrice": 5599
},
"priceAccurate": 5199,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086700131130,
"promoLabels": [
"赠送积分"
],
"promotionInfo": "批量采购享优惠",
"rateCount": 0,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "2801010075804",
"skuCount": 6,
"skuName": "[三年保修 三年专家上门] HUAWEI MateBook B3-420 2021 i5 8GB 512GB 深空灰 45% NTSC色域 14英寸 商用笔记本",
"webVideoPath": "",
"services": [
"仅看有货",
"分期免息",
"优惠商品"
]
},
{
"briefName": "HUAWEI MateStation B515 台式机",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "100",
"isInv": 1,
"mobileVideoPath": "",
"name": "HUAWEI MateStation B515 台式机",
"tag": "新品",
"photoName": "2309E3EAC19408D03275BEF025D245DBmp.png",
"photoPath": "/uomcdn/CN/pms/202205/gbom/6941487207497/",
"picture3DPath": "",
"price": {
"newPrice": 3799,
"oldPrice": 3999
},
"priceAccurate": 3799,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086092274209,
"promoLabels": [
"赠送积分"
],
"promotionInfo": "批量采购享优惠",
"rateCount": 3,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "34010000301",
"skuCount": 7,
"skuName": "[三年保修 三年专家上门] HUAWEI MateStation B515 小机箱 集显 R5-4600G 8GB 1TB HDD 有线键盘 有线鼠标(黑色) 商用台式机",
"webVideoPath": "",
"services": [
"仅看有货",
"分期免息",
"优惠商品"
]
},
{
"briefName": "HUAWEI MateBook B7",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "100",
"isInv": 1,
"mobileVideoPath": "",
"name": "HUAWEI MateBook B7",
"tag": "价保618",
"photoName": "475AE7EE1684FFA352EE92B05E9C5E60739B1F87791D1EBCmp.png",
"photoPath": "/product/6941487222780/",
"picture3DPath": "",
"price": {
"newPrice": 9599,
"oldPrice": 9999
},
"priceAccurate": 9599,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086967025187,
"promoLabels": [
"赠送积分"
],
"promotionInfo": "",
"rateCount": 0,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "2801010076101",
"skuCount": 3,
"skuName": "[三年保修 三年专家上门] HUAWEI MateBook B7 2021 i5 16GB 512GB 深空灰 13.9英寸 商用笔记本",
"webVideoPath": "",
"services": [
"仅看有货",
"分期免息",
"优惠商品"
]
},
{
"briefName": "HUAWEI MateBook B5-430",
"buttonMode": "1",
"carrierCode": "VMALL-HUAWEIDEVICE",
"currencyUnit": "",
"displayToCustomer": "0",
"goodRate": "100",
"isInv": 1,
"mobileVideoPath": "",
"name": "HUAWEI MateBook B5-430",
"tag": "新品",
"photoName": "F25E2E42E8CE4FC87D4DBA2CC3441C7C698586AAFCE6FFFDmp.png",
"photoPath": "/product/6941487231874/",
"picture3DPath": "",
"price": {
"newPrice": 6599,
"oldPrice": 6799
},
"priceAccurate": 6599,
"priceLabel": 1,
"priceMode": 1,
"productId": 10086829728173,
"promoLabels": [
"赠送积分"
],
"promotionInfo": "批量采购享优惠",
"rateCount": 0,
"shopH5Url": "https://m.vmall.com/sc/shop/index.html?carrierCode=VMALL-HUAWEIDEVICE",
"shopMobileUrl": "vmall://com.vmall.client/shop/home?carrierCode=VMALL-HUAWEIDEVICE",
"shopName": "华为商城自营",
"skuCode": "2801010076001",
"skuCount": 6,
"skuName": "[三年保修 三年专家上门] HUAWEI MateBook B5-430 2021 i5 8GB 512GB 深空灰 14英寸 商用笔记本",
"webVideoPath": "",
"services": [
"仅看有货",
"分期免息",
"优惠商品"
]
}
]Click me to view the code js
js
<script src="./json/product_data.js"></script>
// 0.资源服务器的地址
var serverURL = "https://res.vmallres.com/pimages"
// 1.获取元素
var productsEl = document.querySelector(".products")
// 2.动态的展示商品列表
for (var i = 0; i < resultList.length; i++) {
// 2.1 获取一条数据
var resultItemEl = resultList[i]
// 2.2 将这条数据转换成界面一个item
// 创建li
var liEl = document.createElement("li")
liEl.classList.add("item")
productsEl.append(liEl)
// 创建a
var aEl = document.createElement("a")
aEl.href = "#"
liEl.append(aEl)
// 创建img
var albumEl = document.createElement("img")
albumEl.classList.add("album")
albumEl.src = `${serverURL}${resultItemEl.photoPath}800_800_${resultItemEl.photoName}`
aEl.append(albumEl)
// 创建name
var nameEl = document.createElement("div")
nameEl.classList.add("name")
aEl.append(nameEl)
if (resultItemEl.tag) {
var iEl = document.createElement("i")
iEl.classList.add("icon")
iEl.textContent = resultItemEl.tag
nameEl.append(iEl)
}
var spanEl = document.createElement("span")
spanEl.classList.add("title", "nowrap_ellipsis")
spanEl.textContent = resultItemEl.name
nameEl.append(spanEl)
// 创建services
var servicesEl = document.createElement("div")
servicesEl.classList.add("services")
aEl.append(servicesEl)
for (var item of resultItemEl.promoLabels) {
var tipEl = document.createElement("span")
tipEl.classList.add("tip")
tipEl.textContent = item
servicesEl.append(tipEl)
}
// 创建price
var priceEl = document.createElement("div")
priceEl.classList.add("price")
aEl.append(priceEl)
// for (var key in resultItemEl.price) {
// if (key === "newPrice") {
// var value = resultItemEl.price[key]
// var newPriceEl = document.createElement("span")
// newPriceEl.classList.add("new-price")
// newPriceEl.textContent = "¥" + value
// priceEl.append(newPriceEl)
// } else if (key === "oldPrice") {
// var value = resultItemEl.price[key]
// var oldPriceEl = document.createElement("span")
// oldPriceEl.classList.add("old-price")
// oldPriceEl.textContent = "¥" + value
// priceEl.append(oldPriceEl)
// }
// }
// 优化👆🏻注释代码
const priceTypes = {
newPrice: "new-price",
oldPrice: "old-price"
}
for (var key in resultItemEl.price) {
var value = resultItemEl.price[key]
var priceItemEl = document.createElement("span")
priceItemEl.classList.add(priceTypes[key])
priceItemEl.textContent = "¥" + value
priceEl.append(priceItemEl)
}
// 创建comment
var commentEl = document.createElement("div")
commentEl.classList.add("comment")
aEl.append(commentEl)
var countEl = document.createElement("span")
countEl.textContent = resultItemEl.rateCount + "人评价"
commentEl.append(countEl)
var goodEl = document.createElement("span")
goodEl.textContent = resultItemEl.goodRate + "%好评"
commentEl.append(goodEl)
}js
<script src="./json/product_data.js"></script>
// 0.资源服务器的地址
var serverURL = "https://res.vmallres.com/pimages"
// 1.获取元素
var productsEl = document.querySelector(".products")
// 2.动态的展示商品列表
for (var i = 0; i < resultList.length; i++) {
// 2.1 获取一条数据
var resultItemEl = resultList[i]
// 2.2 将这条数据转换成界面一个item
// 创建li
var liEl = document.createElement("li")
liEl.classList.add("item")
productsEl.append(liEl)
// service
servicesString = ""
for (var servicesItem of resultItemEl.services) {
servicesString += `<span class="tip">${servicesItem}</span>`
}
// price
var priceString = ""
for (var key in resultItemEl.price) {
var value = resultItemEl.price[key]
if (key === "oldPrice") {
priceString += `<span class="old-price">¥${value}</span>`
} else if (key === "newPrice") {
priceString += `<span class="new-price">¥${value}</span>`
}
}
liEl.innerHTML = `
<a href="#">
<!-- 封面 -->
<img class="album" src=${serverURL}${resultItemEl.photoPath}800_800_${resultItemEl.photoName} alt="">
<!-- 标题 -->
<div class="name">
<i class="icon">${resultItemEl.tag}</i>
<span class="title nowrap_ellipsis">${resultItemEl.name}</span>
</div>
<!-- 描述 -->
<div class="describe nowrap_ellipsis">${resultItemEl.promotionInfo}</div>
<!-- 服务 -->
<div class="services">${servicesString}</div>
<!-- 价格 -->
<div class="price">${priceString}</div>
<!-- 评论 -->
<div class="comment">
<span>${resultItemEl.rateCount}人评价</span>
<span>${resultItemEl.goodRate}%好评</span>
</div>
</a>
`
}3. 服务优惠的筛选
Click me to view the code js
js
....
// 1.获取元素
...
var operationEl = document.querySelector(".operation")
var discountEl = operationEl.querySelector(".discount")
// 2.定义变量
var discountFilters = [] // 记录用户选择的服务优惠
var resultListFilters = resultList // 过滤数据
// 3.动态的展示商品列表
showResultListAction()
// 封装函数: 通过for循环,展示数据 ✅
function showResultListAction() {
// 防止出现叠加情况
productsEl.innerHTML = ""
for (var i = 0; i < resultListFilters.length; i++) {
// 2.1 获取一条数据
var resultItemEl = resultListFilters[i]
....
}
// 布局对齐
layout()
}
// 4.服务优惠的筛选(从"仅看有货"开始) ✅
for (var i = 1; i < discountEl.children.length; i++) {
// 过滤元素
// 获取对应的discountItemEl
var discountItemEl = discountEl.children[i]
// 监听discountItemEl的点击
discountItemEl.onclick = function () {
// 在 active 和 非active 切换
this.classList.toggle("active")
// 判断是否将关键字添加或者从discountFilters删除掉
if (this.classList.contains("active")) {
discountFilters.push(this.textContent.trim())
} else {
var filterItemEl = this.textContent.trim()
var filterIndex = discountFilters.findIndex(function (item) {
return item === filterItemEl
})
discountFilters.splice(filterIndex, 1)
}
// 过滤resultList数据
filterResultListAction()
}
}
// 5.封装函数: 过滤resultList数据
function filterResultListAction() {
resultListFilters = resultList.filter(function (item) {
var isFlag = true
var services = item.services
for (var filterItemEl of discountFilters) {
if (!services.includes(filterItemEl)) {
isFlag = false
break
}
}
return isFlag
})
// 重新渲染数据
showResultListAction()
}
// 6.封装函数: 布局对齐
function layout() {
var liEl = productsEl.children[0]
// 获取一行存放几个
var count = Math.floor(productsEl.clientWidth / liEl.clientWidth)
// 添加span的个数是列数减-2 ✅
for (var i = 0; i < count - 2; i++) {
var spanEl = document.createElement("span")
spanEl.classList.add("item")
spanEl.style.height = "0"
productsEl.append(spanEl)
}
}4. 排序的筛选
Click me to view the code html
html
<!-- 排序 -->
<ul class="row sort">
<li class="item">排序 :</li>
<li data-action="default" class="item active">综合</li>
<li data-action="goodRate" class="item">好评</li>
<li data-action="rateCount" class="item">评论数</li>
<li data-action="priceAccurate" class="item">价格</li>
</ul>Click me to view the code js
js
// 1.获取元素
...
var sortEl = operationEl.querySelector(".sort")
var activeEl = sortEl.querySelector(".active")
// 2.定义变量
var discountFilters = [] // 记录用户选择的服务优惠
// var resultListFilters = [...resultList] // 过滤数据
var resultListFilters = [].concat(resultList) // 过滤数据
var sortKey = "default" // 默认当前是综合排序
...
// 5.封装函数: 过滤resultList数据
function filterResultListAction() {
// 1.过滤数据
...
// 2.重新展示数据
sortResultListAction(true)
}
...
// 7.排序的筛选(从"综合"开始) ✅
for (var i = 1; i < sortEl.children.length; i++) {
var sortItemEl = sortEl.children[i]
sortItemEl.onclick = function () {
// 1.取消之前的active,添加新的active,记住最新的activeEl
activeEl.classList.remove("active")
this.classList.add("active")
activeEl = this
// 2.获取信息
sortKey = this.dataset.key
// 3.根据key,通过key对数据进行排序
sortResultListAction(false)
}
}
// 封装函数: 排序resultList数据
function sortResultListAction(isJustShow) {
if (sortKey === "default" && !isJustShow) {
filterResultListAction()
} else {
resultListFilters.sort(function (item1, item2) {
// 🔥 为什么不是item2.key,因为key是一个字符串,所以访问对象属性,必须是obj["xx"],而不是obj."xx"
return item2[sortKey] - item1[sortKey]
})
}
showResultListAction()
}5. 完整的代码
Click me to view the code html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>商品筛选</title>
<!-- 样式重置 -->
<link rel="stylesheet" href="./css/reset.css">
<!-- 公共样式 -->
<link rel="stylesheet" href="./css/common.css">
<!-- 站点图标 -->
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon">
<!-- 商品样式 -->
<link rel="stylesheet" href="./css/producs.css">
</head>
<body>
<div class="wrapper">
<!-- 面包屑导航 -->
<div class="crumbs">
<span class="item">首页</span>
<span>></span>
<span class="item">笔记本</span>
</div>
<!-- 操作 -->
<div class="operation">
<!-- 分类 -->
<ul class="row category">
<li class="item">分类 :</li>
<li class="item active">笔记本</li>
<li class="item">MateBook E系列</li>
<li class="item">MateBook D系列</li>
<li class="item">MateBook X系列</li>
<li class="item">华为显示器系列</li>
<li class="item">Matebook B系列</li>
<li class="item nowrap_ellipsis">MateBook数字系列</li>
</ul>
<!-- 服务优惠 -->
<ul class="row discount">
<li class="item">服务优惠 :</li>
<li class="item">仅看有货</li>
<li class="item">分期免息</li>
<li class="item">优惠商品</li>
</ul>
<!-- 排序 -->
<ul class="row sort">
<li class="item">排序 :</li>
<li class="item active" data-key="default">综合</li>
<li class="item" data-key="goodRate">好评</li>
<li class="item" data-key="rateCount">评论数</li>
<li class="item" data-key="priceAccurate">价格</li>
</ul>
</div>
<!-- 商品 -->
<ul class="products"></ul>
</div>
<script src="./json/product_data.js"></script>
<script>
// 0.资源服务器的地址
var serverURL = "https://res.vmallres.com/pimages"
// 1.获取元素
var productsEl = document.querySelector(".products")
var operationEl = document.querySelector(".operation")
var discountEl = operationEl.querySelector(".discount")
var sortEl = operationEl.querySelector(".sort")
var activeEl = sortEl.querySelector(".active")
// 2.定义变量
var discountFilters = [] // 记录用户选择的服务优惠
// var resultListFilters = [...resultList] // 过滤数据
var resultListFilters = [].concat(resultList) // 过滤数据
var sortKey = "default" // 默认当前是综合排序
// 3.动态的展示商品列表
showResultListAction()
// 封装函数: 通过for循环,展示数据 ✅
function showResultListAction() {
// 防止出现叠加情况
productsEl.innerHTML = ""
for (var i = 0; i < resultListFilters.length; i++) {
// 2.1 获取一条数据
var resultItemEl = resultListFilters[i]
// 2.2 将这条数据转换成界面一个item
// 创建li
var liEl = document.createElement("li")
liEl.classList.add("item")
productsEl.append(liEl)
// service
servicesString = ""
for (var servicesItem of resultItemEl.services) {
servicesString += `<span class="tip">${servicesItem}</span>`
}
// price
var priceString = ""
for (var key in resultItemEl.price) {
var value = resultItemEl.price[key]
if (key === "oldPrice") {
priceString += `<span class="old-price">¥${value}</span>`
} else if (key === "newPrice") {
priceString += `<span class="new-price">¥${value}</span>`
}
}
liEl.innerHTML = `
<a href="#">
<!-- 封面 -->
<img class="album" src=${serverURL}${resultItemEl.photoPath}800_800_${resultItemEl.photoName} alt="">
<!-- 标题 -->
<div class="name">
<i class="icon">${resultItemEl.tag}</i>
<span class="title nowrap_ellipsis">${resultItemEl.name}</span>
</div>
<!-- 描述 -->
<div class="describe nowrap_ellipsis">${resultItemEl.promotionInfo}</div>
<!-- 服务 -->
<div class="services">${servicesString}</div>
<!-- 价格 -->
<div class="price">${priceString}</div>
<!-- 评论 -->
<div class="comment">
<span>${resultItemEl.rateCount}人评价</span>
<span>${resultItemEl.goodRate}%好评</span>
</div>
</a>
`
}
// 布局对齐
layout()
}
// 4.服务优惠的筛选(从"仅看有货"开始) ✅
for (var i = 1; i < discountEl.children.length; i++) {
// 过滤元素
// 获取对应的discountItemEl
var discountItemEl = discountEl.children[i]
// 监听discountItemEl的点击
discountItemEl.onclick = function () {
// 在 active 和 非active 切换
this.classList.toggle("active")
// 判断是否将关键字添加或者从discountFilters删除掉
if (this.classList.contains("active")) {
discountFilters.push(this.textContent.trim())
} else {
var filterItemEl = this.textContent.trim()
var filterIndex = discountFilters.findIndex(function (item) {
return item === filterItemEl
})
discountFilters.splice(filterIndex, 1)
}
// 过滤resultList数据
filterResultListAction()
}
}
// 5.封装函数: 过滤resultList数据
function filterResultListAction() {
resultListFilters = resultList.filter(function (item) {
var isFlag = true
var services = item.services
for (var filterItemEl of discountFilters) {
if (!services.includes(filterItemEl)) {
isFlag = false
break
}
}
return isFlag
})
// 重新渲染数据
sortResultListAction(true)
}
// 6.封装函数: 布局对齐
function layout() {
var liEl = productsEl.children[0]
// 获取一行存放几个
var count = Math.floor(productsEl.clientWidth / liEl.clientWidth)
// 添加span的个数是列数减-2 ✅
for (var i = 0; i < count - 2; i++) {
var spanEl = document.createElement("span")
spanEl.classList.add("item")
spanEl.style.height = "0"
productsEl.append(spanEl)
}
}
// 7.排序的筛选(从"综合"开始) ✅
for (var i = 1; i < sortEl.children.length; i++) {
var sortItemEl = sortEl.children[i]
sortItemEl.onclick = function () {
// 1.取消之前的active,添加新的active,记住最新的activeEl
activeEl.classList.remove("active")
this.classList.add("active")
activeEl = this
// 2.获取信息
sortKey = this.dataset.key
// 3.根据key,通过key对数据进行排序
sortResultListAction(false)
}
}
// 封装函数: 排序resultList数据
function sortResultListAction(isJustShow) {
if (sortKey === "default" && !isJustShow) {
filterResultListAction()
} else {
resultListFilters.sort(function (item1, item2) {
// 🔥 为什么不是item2.key,因为key是一个字符串,所以访问对象属性,必须是obj["xx"],而不是obj."xx"
return item2[sortKey] - item1[sortKey]
})
}
showResultListAction()
}
</script>
</body>
</html>23. 华为商城的轮播图(opacity)

1. 界面搭建
Click me to view the code html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>VM-Banner</title>
<!-- 样式重置 -->
<link rel="stylesheet" href="./css/reset.css">
<!-- 站点图标 -->
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon">
<!-- banner -->
<link rel="stylesheet" href="./css/banner.css">
</head>
<body>
<div class="banner">
<!-- 1.图片 -->
<ul class="images">
<li class="item active">
<a href="#">
<img src="./img/banner_01.webp" alt="">
</a>
</li>
...
</ul>
<!-- 2.左右按钮 -->
<div class="control prev"></div>
<div class="control next"></div>
<!-- 3.指示器(小圆点) -->
<div class="indicator">
<div class="item active"></div>
...
</div>
</div>
</body>
</html>Click me to view the code css
css
/* 这里存放的是样式重置 */
html,
body,
div,
ul,
li,
a,
img {
/* 去除默认样式 */
margin: 0;
padding: 0;
}
ul,
li {
/* 去除小圆点 */
list-style: none;
}
a {
/* 去除下划线 */
text-decoration: none;
/* 不要外轮廓 */
outline: none;
}
img {
vertical-align: top;
}Click me to view the code css
css
/* 这里存放的是轮播图样式 */
.banner {
position: relative;
}
/* 1.图片 */
.banner .images {
position: relative;
height: 550px;
}
.banner .images .item {
position: absolute;
left: 0;
top: 0;
width: 100%;
overflow: hidden;
opacity: 0;
}
.banner .images .item.active {
opacity: 1;
}
.banner .images .item a {
/* 必须是block,默认独占一行,宽度为100% */
display: block;
}
.banner .images .item a img {
/* 🚚 图片居中且等比例缩放 */
position: relative;
top: 0;
left: 50%;
transform: translate(-50%);
width: 1440px;
height: 550px;
}
/* 2.左右按钮 */
.banner .control {
position: absolute;
top: 50%;
transform: translate(0, -50%);
width: 41px;
height: 69px;
background: url(../img/spirit_bg.png) no-repeat;
/* 鼠标小手 */
cursor: pointer;
/* 默认隐藏 */
opacity: 0;
}
.banner:hover .control {
opacity: 1;
}
.banner .control.prev {
/* 🚚 1440 - 1200 + 200 = 440px */
left: 440px;
background-position: -84px 50%;
}
.banner .control.prev:hover {
background-position: 0 50%;
}
.banner .control.next {
right: 440px;
background-position: -125px 50%;
}
.banner .control.next:hover {
background-position: -42px 50%;
}
/* 3.指示器(小圆点) */
.banner .indicator {
position: absolute;
left: 50%;
bottom: 24px;
transform: translate(-50%, 0);
height: 32px;
display: flex;
/* 垂直居中 */
align-items: center;
/* 水平居中 */
justify-content: space-between;
}
.banner .indicator .item {
width: 8px;
height: 8px;
margin: 0 6px;
background-color: rgba(0, 0, 0, 0.2);
border-radius: 50%;
/* 鼠标小手 */
cursor: pointer;
}
.banner .indicator .item.active {
width: 12px;
background-color: #fff;
}2. 动态数据展示
Click me to view the code js
js
// banner_data.js
var banners = [
{
"actionUrlWap": "",
"actionUrlWeb": "https://www.vmall.com/portal/activity/index.html?pn=zhuhuichangpc",
"actonUrl": "",
"bgColor": "#ED2E35",
"dataSourceCode": "DB000044",
"dataSourceType": "ad",
"id": 20533,
"imgUrl": "/uomcdn/CN/cms/202202/F1B873739558FB5D1059099F4220ABA4.jpg",
"imgWebpUrlMap": {
"webp_1": "/uomcdn/CN/cms/202202/F1B873739558FB5D1059099F4220ABA4.jpg.25.webp",
"webp_2": "/uomcdn/CN/cms/202202/F1B873739558FB5D1059099F4220ABA4.jpg.50.webp",
"webp_3": "/uomcdn/CN/cms/202202/F1B873739558FB5D1059099F4220ABA4.jpg.75.webp",
"webp_4": "/uomcdn/CN/cms/202202/F1B873739558FB5D1059099F4220ABA4.jpg.webp"
},
"tagSelected": "{}",
"title": "主"
},
{
"actionUrlWap": "",
"actionUrlWeb": "https://www.vmall.com/portal/activity/index.html?pn=huaweizonePC",
"actonUrl": "",
"bgColor": "#ED2E35",
"dataSourceCode": "DB000044",
"dataSourceType": "ad",
"id": 17691,
"imgUrl": "/uomcdn/CN/cms/202202/9B8652362711564FEB2B33793250D8B9.png",
"imgWebpUrlMap": {
"webp_1": "/uomcdn/CN/cms/202202/9B8652362711564FEB2B33793250D8B9.png.25.webp",
"webp_2": "/uomcdn/CN/cms/202202/9B8652362711564FEB2B33793250D8B9.png.50.webp",
"webp_3": "/uomcdn/CN/cms/202202/9B8652362711564FEB2B33793250D8B9.png.75.webp",
"webp_4": "/uomcdn/CN/cms/202202/9B8652362711564FEB2B33793250D8B9.png.webp"
},
"tagSelected": "{}",
"title": "华为"
},
{
"actionUrlWap": "",
"actionUrlWeb": "https://www.vmall.com/portal/activity/index.html?pageId=401022361",
"actonUrl": "",
"bgColor": "#ED2E35",
"dataSourceCode": "DB000044",
"dataSourceType": "ad",
"id": 839,
"imgUrl": "/uomcdn/CN/cms/202202/55338EF54406E2D3D6FAC2BF6C9D231D.png",
"imgWebpUrlMap": {
"webp_1": "/uomcdn/CN/cms/202202/55338EF54406E2D3D6FAC2BF6C9D231D.png.25.webp",
"webp_2": "/uomcdn/CN/cms/202202/55338EF54406E2D3D6FAC2BF6C9D231D.png.50.webp",
"webp_3": "/uomcdn/CN/cms/202202/55338EF54406E2D3D6FAC2BF6C9D231D.png.75.webp",
"webp_4": "/uomcdn/CN/cms/202202/55338EF54406E2D3D6FAC2BF6C9D231D.png.webp"
},
"tagSelected": "{}",
"title": "教育办公"
},
{
"actionUrlMp": "",
"actionUrlWap": "",
"actionUrlWeb": "https://www.vmall.com/portal/activity/index.html?pn=harmonyosconnectpc",
"actonUrl": "",
"bgColor": "#ED2E35",
"dataSourceCode": "DB000044",
"dataSourceType": "ad",
"id": 29135,
"imgUrl": "/uomcdn/CN/cms/202202/B53ABB8B90DC11AABDDE6F379FF57866.png",
"imgWebpUrlMap": {
"webp_1": "/uomcdn/CN/cms/202202/B53ABB8B90DC11AABDDE6F379FF57866.png.25.webp",
"webp_2": "/uomcdn/CN/cms/202202/B53ABB8B90DC11AABDDE6F379FF57866.png.50.webp",
"webp_3": "/uomcdn/CN/cms/202202/B53ABB8B90DC11AABDDE6F379FF57866.png.75.webp",
"webp_4": "/uomcdn/CN/cms/202202/B53ABB8B90DC11AABDDE6F379FF57866.png.webp"
},
"tagSelected": "{}",
"title": "行业"
},
{
"actionUrlWap": "",
"actionUrlWeb": "https://www.vmall.com/portal/activity/index.html?pn=zhixuanpc",
"actonUrl": "",
"bgColor": "#ED2E35",
"dataSourceCode": "DB000044",
"dataSourceType": "ad",
"id": 9059,
"imgUrl": "/uomcdn/CN/cms/202202/15550D184131C453A2CED9E443AEDDF8.jpg",
"imgWebpUrlMap": {
"webp_1": "/uomcdn/CN/cms/202202/15550D184131C453A2CED9E443AEDDF8.jpg.25.webp",
"webp_2": "/uomcdn/CN/cms/202202/15550D184131C453A2CED9E443AEDDF8.jpg.50.webp",
"webp_3": "/uomcdn/CN/cms/202202/15550D184131C453A2CED9E443AEDDF8.jpg.75.webp",
"webp_4": "/uomcdn/CN/cms/202202/15550D184131C453A2CED9E443AEDDF8.jpg.webp"
},
"tagSelected": "{}",
"title": "智选"
},
{
"actionUrlWap": "",
"actionUrlWeb": "https://www.vmall.com/portal/activity/index.html?pn=zhcxaitoweb",
"actonUrl": "",
"bgColor": "#ED2E35",
"dataSourceCode": "DB000044",
"dataSourceType": "ad",
"id": 18893,
"imgUrl": "/uomcdn/CN/cms/202201/3E994BF010D07F8CD8E8B445514A06F5.png",
"imgWebpUrlMap": {
"webp_1": "/uomcdn/CN/cms/202201/3E994BF010D07F8CD8E8B445514A06F5.png.25.webp",
"webp_2": "/uomcdn/CN/cms/202201/3E994BF010D07F8CD8E8B445514A06F5.png.50.webp",
"webp_3": "/uomcdn/CN/cms/202201/3E994BF010D07F8CD8E8B445514A06F5.png.75.webp",
"webp_4": "/uomcdn/CN/cms/202201/3E994BF010D07F8CD8E8B445514A06F5.png.webp"
},
"tagSelected": "{}",
"title": "AITO"
},
{
"actionUrlMp": "",
"actionUrlWap": "",
"actionUrlWeb": "https://www.vmall.com/portal/activity/index.html?pageId=401021384",
"actonUrl": "",
"bgColor": "#ED2E35",
"dataSourceCode": "DB000044",
"dataSourceType": "ad",
"id": 29439,
"imgUrl": "/uomcdn/CN/cms/202202/B1726D36C05F0486A3D07605F34A4C7D.png",
"imgWebpUrlMap": {
"webp_1": "/uomcdn/CN/cms/202202/B1726D36C05F0486A3D07605F34A4C7D.png.25.webp",
"webp_2": "/uomcdn/CN/cms/202202/B1726D36C05F0486A3D07605F34A4C7D.png.50.webp",
"webp_3": "/uomcdn/CN/cms/202202/B1726D36C05F0486A3D07605F34A4C7D.png.75.webp",
"webp_4": "/uomcdn/CN/cms/202202/B1726D36C05F0486A3D07605F34A4C7D.png.webp"
},
"tagSelected": "{}",
"title": "智慧办公"
},
{
"actionUrlWap": "",
"actionUrlWeb": "https://www.vmall.com/portal/activity/index.html?pageId=301002069",
"actonUrl": "",
"bgColor": "#ED2E35",
"dataSourceCode": "DB000044",
"dataSourceType": "ad",
"id": 19369,
"imgUrl": "/uomcdn/CN/cms/202202/083AA2A10A88835A2BE7A786DC18F85F.jpg",
"imgWebpUrlMap": {
"webp_1": "/uomcdn/CN/cms/202202/083AA2A10A88835A2BE7A786DC18F85F.jpg.25.webp",
"webp_2": "/uomcdn/CN/cms/202202/083AA2A10A88835A2BE7A786DC18F85F.jpg.50.webp",
"webp_3": "/uomcdn/CN/cms/202202/083AA2A10A88835A2BE7A786DC18F85F.jpg.75.webp",
"webp_4": "/uomcdn/CN/cms/202202/083AA2A10A88835A2BE7A786DC18F85F.jpg.webp"
},
"tagSelected": "{}",
"title": "莫塞尔"
}
]Click me to view the code html
html
<div class="banner">
<!-- 1.图片 -->
<ul class="images"></ul>
<!-- 2.左右按钮 -->
<div class="control prev"></div>
<div class="control next"></div>
<!-- 3.指示器(小圆点) -->
<div class="indicator"></div>
</div>Click me to view the code js
js
<script src="./json/banner_data.js"></script>
// 0.资源服务器地址
var serverURL = "https://res.vmallres.com"
// 1.获取元素
var bannerEl = document.querySelector(".banner")
var imagesEl = bannerEl.querySelector(".images")
var indicatorEl = bannerEl.querySelector(".indicator")
// 2.定义变量
var bannersCount = banners.length // banners的长度大小
// 3.根据数据动态添加页面内容
// 3.1 动态添加图片相关内容
for (var i = 0; i < bannersCount; i++) {
// 3.1 获取数据
var banner = banners[i]
// 3.2创建li元素
var itemEl = document.createElement("li")
itemEl.classList.add("item")
// 默认显示第一张图片
if (i === 0) itemEl.classList.add("active")
imagesEl.append(itemEl)
// 🚚 方法一: 一个一个创建元素
// 3.3创建a元素
// var aEl = document.createElement("a")
// aEl.href = "#"
// itemEl.append(aEl)
// // 3.4创建img元素
// var imgEl = document.createElement("img")
// imgEl.src = `${serverURL}${banner.imgUrl}`
// aEl.append(imgEl)
// 🚚 方法二: innerHTML
itemEl.innerHTML = `
<a href="#">
<img src = "${serverURL}${banner.imgUrl}">
</a>
`
}
// 3.2 动态添加指示器(小圆点)内容
for (var i = 0; i < bannersCount; i++) {
var itemEl = document.createElement("div")
itemEl.classList.add("item")
// 默认显示第一张图片
if (i === 0) itemEl.classList.add("active")
indicatorEl.append(itemEl)
}3. 自动轮播
Click me to view the code css
css
.banner .images .item {
...
/* 添加过渡动画 */
transition: opacity 500ms ease;
}Click me to view the code js
js
...
// 2.定义变量
...
var currentIndex = 0 // 当前索引
var imagesActiveEl = imagesEl.querySelector(".active") // 图片选中
var indicatorActiveEl = indicatorEl.querySelector(".active") // 指示器(小圆点)选中
...
// 4.自动轮播
setInterval(function () {
currentIndex++
if (currentIndex === bannersCount) currentIndex = 0
// 切换轮播图
switchBanner()
}, 3000)
// 封装函数: 切换轮播图
function switchBanner() {
// 1.切换图片的item
// 移除之前的active,添加新的active,记住最新的activeEl
imagesActiveEl.classList.remove("active")
var currentItemEl = imagesEl.children[currentIndex]
currentItemEl.classList.add("active")
imagesActiveEl = currentItemEl
// 2.切换指示器(小圆点)的item
indicatorActiveEl.classList.remove("active")
var currentInItemEl = indicatorEl.children[currentIndex]
currentInItemEl.classList.add("active")
indicatorActiveEl = currentInItemEl
}js
...
// 2.定义变量
...
var currentIndex = 0 // 当前索引
var previousIndex = 0 // 上一个索引
var currentIndex = 0 // 当前索引
...
// 4.自动轮播
setInterval(function () {
previousIndex = currentIndex
currentIndex++
if (currentIndex === bannersCount) currentIndex = 0
// 切换轮播图
switchBanner()
}, 3000)
// 封装函数: 切换轮播图
function switchBanner() {
// 1.切换图片的item
// 让currentIndex变成active状态,让previousIndex变成普通状态
var currentItemEl = imagesEl.children[currentIndex]
var previousItemEl = imagesEl.children[previousIndex]
previousItemEl.classList.remove("active")
currentItemEl.classList.add("active")
// 2.切换指示器(小圆点)的item
var currentInItemEl = indicatorEl.children[currentIndex]
var previousInItemEl = indicatorEl.children[previousIndex]
previousInItemEl.classList.remove("active")
currentInItemEl.classList.add("active")
}👆🏻方法 推荐使用第二种方法
4. 鼠标移动到banner上清除定时器
Click me to view the code js
js
...
// 2.定义变量
...
var timeID = null // 定时器
...
// 4.自动轮播(开启定时器)
startTime()
// 5.鼠标移动到banner上清除定时器
bannerEl.onmouseenter = function () {
// 清除定时器
stopTime()
}
// 6.鼠标离开banner开启定时器
bannerEl.onmouseleave = function () {
//开启定时器
startTime()
}
...
// 封装函数: 开启定时器
function startTime() {
if (timeID) return
timeID = setInterval(function () {
previousIndex = currentIndex
currentIndex++
if (currentIndex === bannersCount) currentIndex = 0
// 切换轮播图
switchBanner()
}, 3000)
}
// 封装函数: 清除定时器
function stopTime() {
if (!timeID) return
clearInterval(timeID)
timeID = null // 清除定时器之后, 必须timeID赋值为null
}5. 指示器(小圆点)的点击
Click me to view the code js
js
...
// 3.2 动态添加指示器(小圆点)内容
for (var i = 0; i < bannersCount; i++) {
...
// 监听指示器(小圆点)的点击
// 🚚 方法一
// 获取索引
itemEl.index = i
itemEl.onclick = function() {
previousIndex = currentIndex
currentIndex = this.index
// 切换轮播图
switchBanner()
}
}
...js
// 7.监听指示器(小圆点)的点击
indicatorEl.onclick = function (event) {
if (event.target === this) return
var currentInItemEl = event.target
// 获取索引
// 🚚 方法一: for
// for (var i = 0; i < indicatorEl.children.length; i++) {
// var itemEl = indicatorEl.children[i]
// if (itemEl === currentInItemEl) {
// var index = i
// break
// }
// }
// 🚚 方法二: indexOf
// var index = Array.from(this.children).indexOf(currentInItemEl)
// 🚚 方法一: findIndex
var index = Array.from(this.children).findIndex(function (item) {
return item === currentInItemEl
})
previousIndex = currentIndex
currentIndex = index
// 切换轮播图
switchBanner()
}👆🏻方法 推荐使用第一种方法
6. 左右按钮的点击
Click me to view the code js
js
// 1.获取元素
...
var prevBtnEl = bannerEl.querySelector(".prev")
var nextBtnEl = bannerEl.querySelector(".next")
...
// 6.上下按钮的点击切换
prevBtnEl.onclick = function () {
// 找到上一个
previousIndex = currentIndex
currentIndex--
if (currentIndex === -1) currentIndex = bannersCount - 1
// 切换轮播图
switchBanner()
}
nextBtnEl.onclick = function () {
// 找到下一个
previousIndex = currentIndex
currentIndex++
if (currentIndex === bannersCount) currentIndex = 0
// 切换轮播图
switchBanner()
}
代码重构
Click me to view the code js
js
...
// 简洁写法: nextBtnEl.onclick = nextSwitch 不推荐 阅读性太差 🔥
nextBtnEl.onclick = function () {
// 切换下一个
nextSwitch()
}
...
// 封装函数: 开启定时器
function startTime() {
if (timeID) return
// 简洁写法: timeID = setInterval(nextSwitch,3000) 不推荐 阅读性太差 🔥
timeID = setInterval(function () {
// 切换下一个
nextSwitch()
}, 3000)
}
// 封装函数: 播放下一个
function nextSwitch() {
// 找到下一个
previousIndex = currentIndex
currentIndex++
if (currentIndex === bannersCount) currentIndex = 0
// 切换轮播图
switchBanner()
}
...
// 封装函数: 开启定时器
function startTime() {
if (timeID) return
// 简洁写法: timeID = setInterval(nextSwitch,3000) 不推荐 阅读性太差 🔥
timeID = setInterval(function () {
// 切换下一个
nextSwitch()
}, 3000)
}
// 封装函数: 播放下一个
function nextSwitch() {
// 找到下一个
previousIndex = currentIndex
currentIndex++
if (currentIndex === bannersCount) currentIndex = 0
// 切换轮播图
switchBanner()
}7. 离开浏览器窗口时,清除定时器
Click me to view the code js
js
// window的焦点(离开浏览器窗口时,清除定时器)
document.onvisibilitychange = function () {
// 如果离开当前浏览器页面,清除定时器; 如果在当前浏览器页面,开启定时器;
if (this.visibilityState === "hidden") {
stopTime()
} else if (this.visibilityState === "visible") {
startTime()
}
}24. 华为商城的轮播图(transform: translateX())

1. 界面搭建
Click me to view the code html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 站点图标 -->
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon">
<!-- 样式重置 -->
<link rel="stylesheet" href="./css/reset.css">
<!-- banner -->
<link rel="stylesheet" href="./css/banner.css">
</head>
<body>
<div class="banner">
<!-- 1.图片 -->
<ul class="images">
<li class="item">
<a href="#">
<img src="./img/banner_01.webp" alt="">
</a>
</li>
...
</ul>
<!-- 2.左右按钮 -->
<div class="control prev"></div>
<div class="control next"></div>
<!-- 3.指示器(小圆点) -->
<div class="indicator">
<div class="item active"></div>
</div>
</div>
</body>
</html>Click me to view the code css
css
/* 这里存放的是样式重置 */
html,body,div,ul,li,a,img {
margin: 0;
padding: 0;
}
ul,li {
/* 去除小圆点 */
list-style: none;
}
a {
/* 去除下划线 */
text-decoration: none;
/* 不要外轮廓 */
outline: none;
}
img {
/* 顶部基线对齐 */
vertical-align: top;
}Click me to view the code css
css
/* 这是存放的是轮播图的样式 */
.banner {
position: relative;
overflow: hidden;
}
/* 1.图片 */
.banner .images {
position: relative;
height: 550px;
}
.banner .images .item {
position: absolute;
top: 0;
left: 0;
width: 100%;
overflow: hidden;
}
.banner .images .item a {
display: block;
}
.banner .images .item a img {
/* 图片水平居中且等比例缩放 */
position: relative;
left: 50%;
transform: translate(-50%);
width: 1440px;
height: 550px;
}
/* 2.左右按钮 */
.banner .control {
/* 垂直居中 */
position: absolute;
top: 50%;
transform: translate(0, -50%);
width: 41px;
height: 69px;
background: url(../img/sprite_bg.png) no-repeat;
/* 默认隐藏 */
opacity: 0;
/* 鼠标小手 */
cursor: pointer;
}
.banner:hover .control {
opacity: 1;
}
.banner .control.prev {
/* (1440 - 1200)/2 +200 = 320px */
left: 320px;
background-position: -84px 50%;
}
.banner .control.prev:hover {
background-position: 0 50%;
}
.banner .control.next {
right: 320px;
background-position: -125px 50%;
}
.banner .control.next:hover {
background-position: -42px 50%;
}
/* 3.指示器(小圆点) */
.banner .indicator {
position: absolute;
bottom: 24px;
left: 50%;
transform: translate(-50%, 0);
height: 32px;
display: flex;
/* 垂直居中 */
align-items: center;
}
.banner .indicator .item {
width: 8px;
height: 8px;
margin: 0 6px;
background-color: rgba(0, 0, 0, .2);
border-radius: 50%;
/* 鼠标小手 */
cursor: pointer;
}
.banner .indicator .item.active {
width: 12px;
background-color: #fff;
}2. 动态数据展示
Click me to view the code js
js
// banner_data.js
var banners = [
{
"actionUrlWap": "",
"actionUrlWeb": "https://www.vmall.com/portal/activity/index.html?pn=zhuhuichangpc",
"actonUrl": "",
"bgColor": "#ED2E35",
"dataSourceCode": "DB000044",
"dataSourceType": "ad",
"id": 20533,
"imgUrl": "/uomcdn/CN/cms/202202/F1B873739558FB5D1059099F4220ABA4.jpg",
"imgWebpUrlMap": {
"webp_1": "/uomcdn/CN/cms/202202/F1B873739558FB5D1059099F4220ABA4.jpg.25.webp",
"webp_2": "/uomcdn/CN/cms/202202/F1B873739558FB5D1059099F4220ABA4.jpg.50.webp",
"webp_3": "/uomcdn/CN/cms/202202/F1B873739558FB5D1059099F4220ABA4.jpg.75.webp",
"webp_4": "/uomcdn/CN/cms/202202/F1B873739558FB5D1059099F4220ABA4.jpg.webp"
},
"tagSelected": "{}",
"title": "主"
},
{
"actionUrlWap": "",
"actionUrlWeb": "https://www.vmall.com/portal/activity/index.html?pn=huaweizonePC",
"actonUrl": "",
"bgColor": "#ED2E35",
"dataSourceCode": "DB000044",
"dataSourceType": "ad",
"id": 17691,
"imgUrl": "/uomcdn/CN/cms/202202/9B8652362711564FEB2B33793250D8B9.png",
"imgWebpUrlMap": {
"webp_1": "/uomcdn/CN/cms/202202/9B8652362711564FEB2B33793250D8B9.png.25.webp",
"webp_2": "/uomcdn/CN/cms/202202/9B8652362711564FEB2B33793250D8B9.png.50.webp",
"webp_3": "/uomcdn/CN/cms/202202/9B8652362711564FEB2B33793250D8B9.png.75.webp",
"webp_4": "/uomcdn/CN/cms/202202/9B8652362711564FEB2B33793250D8B9.png.webp"
},
"tagSelected": "{}",
"title": "华为"
},
{
"actionUrlWap": "",
"actionUrlWeb": "https://www.vmall.com/portal/activity/index.html?pageId=401022361",
"actonUrl": "",
"bgColor": "#ED2E35",
"dataSourceCode": "DB000044",
"dataSourceType": "ad",
"id": 839,
"imgUrl": "/uomcdn/CN/cms/202202/55338EF54406E2D3D6FAC2BF6C9D231D.png",
"imgWebpUrlMap": {
"webp_1": "/uomcdn/CN/cms/202202/55338EF54406E2D3D6FAC2BF6C9D231D.png.25.webp",
"webp_2": "/uomcdn/CN/cms/202202/55338EF54406E2D3D6FAC2BF6C9D231D.png.50.webp",
"webp_3": "/uomcdn/CN/cms/202202/55338EF54406E2D3D6FAC2BF6C9D231D.png.75.webp",
"webp_4": "/uomcdn/CN/cms/202202/55338EF54406E2D3D6FAC2BF6C9D231D.png.webp"
},
"tagSelected": "{}",
"title": "教育办公"
},
{
"actionUrlMp": "",
"actionUrlWap": "",
"actionUrlWeb": "https://www.vmall.com/portal/activity/index.html?pn=harmonyosconnectpc",
"actonUrl": "",
"bgColor": "#ED2E35",
"dataSourceCode": "DB000044",
"dataSourceType": "ad",
"id": 29135,
"imgUrl": "/uomcdn/CN/cms/202202/B53ABB8B90DC11AABDDE6F379FF57866.png",
"imgWebpUrlMap": {
"webp_1": "/uomcdn/CN/cms/202202/B53ABB8B90DC11AABDDE6F379FF57866.png.25.webp",
"webp_2": "/uomcdn/CN/cms/202202/B53ABB8B90DC11AABDDE6F379FF57866.png.50.webp",
"webp_3": "/uomcdn/CN/cms/202202/B53ABB8B90DC11AABDDE6F379FF57866.png.75.webp",
"webp_4": "/uomcdn/CN/cms/202202/B53ABB8B90DC11AABDDE6F379FF57866.png.webp"
},
"tagSelected": "{}",
"title": "行业"
},
{
"actionUrlWap": "",
"actionUrlWeb": "https://www.vmall.com/portal/activity/index.html?pn=zhixuanpc",
"actonUrl": "",
"bgColor": "#ED2E35",
"dataSourceCode": "DB000044",
"dataSourceType": "ad",
"id": 9059,
"imgUrl": "/uomcdn/CN/cms/202202/15550D184131C453A2CED9E443AEDDF8.jpg",
"imgWebpUrlMap": {
"webp_1": "/uomcdn/CN/cms/202202/15550D184131C453A2CED9E443AEDDF8.jpg.25.webp",
"webp_2": "/uomcdn/CN/cms/202202/15550D184131C453A2CED9E443AEDDF8.jpg.50.webp",
"webp_3": "/uomcdn/CN/cms/202202/15550D184131C453A2CED9E443AEDDF8.jpg.75.webp",
"webp_4": "/uomcdn/CN/cms/202202/15550D184131C453A2CED9E443AEDDF8.jpg.webp"
},
"tagSelected": "{}",
"title": "智选"
},
{
"actionUrlWap": "",
"actionUrlWeb": "https://www.vmall.com/portal/activity/index.html?pn=zhcxaitoweb",
"actonUrl": "",
"bgColor": "#ED2E35",
"dataSourceCode": "DB000044",
"dataSourceType": "ad",
"id": 18893,
"imgUrl": "/uomcdn/CN/cms/202201/3E994BF010D07F8CD8E8B445514A06F5.png",
"imgWebpUrlMap": {
"webp_1": "/uomcdn/CN/cms/202201/3E994BF010D07F8CD8E8B445514A06F5.png.25.webp",
"webp_2": "/uomcdn/CN/cms/202201/3E994BF010D07F8CD8E8B445514A06F5.png.50.webp",
"webp_3": "/uomcdn/CN/cms/202201/3E994BF010D07F8CD8E8B445514A06F5.png.75.webp",
"webp_4": "/uomcdn/CN/cms/202201/3E994BF010D07F8CD8E8B445514A06F5.png.webp"
},
"tagSelected": "{}",
"title": "AITO"
},
{
"actionUrlMp": "",
"actionUrlWap": "",
"actionUrlWeb": "https://www.vmall.com/portal/activity/index.html?pageId=401021384",
"actonUrl": "",
"bgColor": "#ED2E35",
"dataSourceCode": "DB000044",
"dataSourceType": "ad",
"id": 29439,
"imgUrl": "/uomcdn/CN/cms/202202/B1726D36C05F0486A3D07605F34A4C7D.png",
"imgWebpUrlMap": {
"webp_1": "/uomcdn/CN/cms/202202/B1726D36C05F0486A3D07605F34A4C7D.png.25.webp",
"webp_2": "/uomcdn/CN/cms/202202/B1726D36C05F0486A3D07605F34A4C7D.png.50.webp",
"webp_3": "/uomcdn/CN/cms/202202/B1726D36C05F0486A3D07605F34A4C7D.png.75.webp",
"webp_4": "/uomcdn/CN/cms/202202/B1726D36C05F0486A3D07605F34A4C7D.png.webp"
},
"tagSelected": "{}",
"title": "智慧办公"
},
{
"actionUrlWap": "",
"actionUrlWeb": "https://www.vmall.com/portal/activity/index.html?pageId=301002069",
"actonUrl": "",
"bgColor": "#ED2E35",
"dataSourceCode": "DB000044",
"dataSourceType": "ad",
"id": 19369,
"imgUrl": "/uomcdn/CN/cms/202202/083AA2A10A88835A2BE7A786DC18F85F.jpg",
"imgWebpUrlMap": {
"webp_1": "/uomcdn/CN/cms/202202/083AA2A10A88835A2BE7A786DC18F85F.jpg.25.webp",
"webp_2": "/uomcdn/CN/cms/202202/083AA2A10A88835A2BE7A786DC18F85F.jpg.50.webp",
"webp_3": "/uomcdn/CN/cms/202202/083AA2A10A88835A2BE7A786DC18F85F.jpg.75.webp",
"webp_4": "/uomcdn/CN/cms/202202/083AA2A10A88835A2BE7A786DC18F85F.jpg.webp"
},
"tagSelected": "{}",
"title": "莫塞尔"
}
]Click me to view the code html
html
<div class="banner">
<!-- 1.图片 -->
<ul class="images"></ul>
<!-- 2.左右按钮 -->
<div class="control prev"></div>
<div class="control next"></div>
<!-- 3.指示器(小圆点) -->
<div class="indicator"></div>
</div>Click me to view the code js
js
<script src="./json/banner_data.js"></script>
// 0.资源服务器地址
var serverURL = "https://res.vmallres.com"
// 1.获取元素
var bannerEl = document.querySelector(".banner")
var imagesEl = bannerEl.querySelector(".images")
var indicatorEl = bannerEl.querySelector(".indicator")
// 2.定义变量
var bannersCount = banners.length // banners的长度大小
// 3.根据数据动态添加页面内容
// 3.1 动态添加图片相关内容
for (var i = 0; i < bannersCount; i++) {
// 3.1 获取数据
var banner = banners[i]
// 3.2创建li元素
var itemEl = document.createElement("li")
itemEl.classList.add("item")
imagesEl.append(itemEl)
// 🚚 方法一: 一个一个创建元素
// 3.3创建a元素
// var aEl = document.createElement("a")
// aEl.href = "#"
// itemEl.append(aEl)
// // 3.4创建img元素
// var imgEl = document.createElement("img")
// imgEl.src = `${serverURL}${banner.imgUrl}`
// aEl.append(imgEl)
// 🚚 方法二: innerHTML
itemEl.innerHTML = `
<a href="#">
<img src = "${serverURL}${banner.imgUrl}">
</a>
`
// 设置itemEl的样式(left)
itemEl.style.left = `${i * 100}%`
}
// 3.2 动态添加指示器(小圆点)内容
for (var i = 0; i < bannersCount; i++) {
var itemEl = document.createElement("div")
itemEl.classList.add("item")
// 默认显示第一张图片
if (i === 0) itemEl.classList.add("active")
indicatorEl.append(itemEl)
}3. 自动轮播
Click me to view the code js
js
...
// 2.定义变量
...
var currentIndex = 0 // 当前索引
var imagesActiveEl = imagesEl.querySelector(".active") // 图片选中
var indicatorActiveEl = indicatorEl.querySelector(".active") // 指示器(小圆点)选中
...
// 4.自动轮播
setInterval(function () {
currentIndex++
if (currentIndex === bannersCount) currentIndex = 0
// 切换轮播图
switchBanner()
}, 3000)
// 封装函数: 切换轮播图
function switchBanner() {
// 1.切换图片的item
imagesEl.style.transform = `translateX(${-currentIndex * 100}%)`
imagesEl.style.transition = "all 1000ms ease"
// 2.切换指示器(小圆点)的item
indicatorActiveEl.classList.remove("active")
var currentInItemEl = indicatorEl.children[currentIndex]
currentInItemEl.classList.add("active")
indicatorActiveEl = currentInItemEl
}js
...
// 2.定义变量
...
var currentIndex = 0 // 当前索引
var previousIndex = 0 // 上一个索引
var currentIndex = 0 // 当前索引
...
// 4.自动轮播
setInterval(function () {
previousIndex = currentIndex
currentIndex++
if (currentIndex === bannersCount) currentIndex = 0
// 切换轮播图
switchBanner()
}, 3000)
// 封装函数: 切换轮播图
function switchBanner() {
// 1.切换图片的item
imagesEl.style.transform = `translateX(${-currentIndex * 100}%)`
imagesEl.style.transition = "all 1000ms ease"
// 2.切换指示器(小圆点)的item
var currentInItemEl = indicatorEl.children[currentIndex]
var previousInItemEl = indicatorEl.children[previousIndex]
previousInItemEl.classList.remove("active")
currentInItemEl.classList.add("active")
}👆🏻方法 推荐使用第二种方法
4. 鼠标移动到banner上清除定时器
Click me to view the code js
js
...
// 2.定义变量
...
var timeID = null // 定时器
...
// 4.自动轮播(开启定时器)
startTime()
// 5.鼠标移动到banner上清除定时器
bannerEl.onmouseenter = function () {
// 清除定时器
stopTime()
}
// 6.鼠标离开banner开启定时器
bannerEl.onmouseleave = function () {
//开启定时器
startTime()
}
...
// 封装函数: 开启定时器
function startTime() {
if (timeID) return
timeID = setInterval(function () {
previousIndex = currentIndex
currentIndex++
if (currentIndex === bannersCount) currentIndex = 0
// 切换轮播图
switchBanner()
}, 3000)
}
// 封装函数: 清除定时器
function stopTime() {
if (!timeID) return
clearInterval(timeID)
timeID = null // 清除定时器之后, 必须timeID赋值为null
}5. 指示器(小圆点)的点击
Click me to view the code js
js
...
// 3.2 动态添加指示器(小圆点)内容
for (var i = 0; i < bannersCount; i++) {
...
// 监听指示器(小圆点)的点击
// 🚚 方法一
// 获取索引
itemEl.index = i
itemEl.onclick = function() {
previousIndex = currentIndex
currentIndex = this.index
// 切换轮播图
switchBanner()
}
}
...js
// 7.监听指示器(小圆点)的点击
indicatorEl.onclick = function (event) {
if (event.target === this) return
var currentInItemEl = event.target
// 获取索引
// 🚚 方法一: for
// for (var i = 0; i < indicatorEl.children.length; i++) {
// var itemEl = indicatorEl.children[i]
// if (itemEl === currentInItemEl) {
// var index = i
// break
// }
// }
// 🚚 方法二: indexOf
// var index = Array.from(this.children).indexOf(currentInItemEl)
// 🚚 方法一: findIndex
var index = Array.from(this.children).findIndex(function (item) {
return item === currentInItemEl
})
previousIndex = currentIndex
currentIndex = index
// 切换轮播图
switchBanner()
}👆🏻方法 推荐使用第一种方法
6. 左右按钮的点击
Click me to view the code js
js
// 1.获取元素
...
var prevBtnEl = bannerEl.querySelector(".prev")
var nextBtnEl = bannerEl.querySelector(".next")
...
// 6.上下按钮的点击切换
prevBtnEl.onclick = function () {
// 找到上一个
previousIndex = currentIndex
currentIndex--
if (currentIndex === -1) currentIndex = bannersCount - 1
// 切换轮播图
switchBanner()
}
nextBtnEl.onclick = function () {
// 找到下一个
previousIndex = currentIndex
currentIndex++
if (currentIndex === bannersCount) currentIndex = 0
// 切换轮播图
switchBanner()
}
代码重构
Click me to view the code js
js
...
// 简洁写法: nextBtnEl.onclick = nextSwitch 不推荐 阅读性太差 🔥
nextBtnEl.onclick = function () {
// 切换下一个
nextSwitch()
}
...
// 封装函数: 开启定时器
function startTime() {
if (timeID) return
// 简洁写法: timeID = setInterval(nextSwitch,3000) 不推荐 阅读性太差 🔥
timeID = setInterval(function () {
// 切换下一个
nextSwitch()
}, 3000)
}
// 封装函数: 播放下一个
function nextSwitch() {
// 找到下一个
previousIndex = currentIndex
currentIndex++
if (currentIndex === bannersCount) currentIndex = 0
// 切换轮播图
switchBanner()
}
...
// 封装函数: 开启定时器
function startTime() {
if (timeID) return
// 简洁写法: timeID = setInterval(nextSwitch,3000) 不推荐 阅读性太差 🔥
timeID = setInterval(function () {
// 切换下一个
nextSwitch()
}, 3000)
}
// 封装函数: 播放下一个
function nextSwitch() {
// 找到下一个
previousIndex = currentIndex
currentIndex++
if (currentIndex === bannersCount) currentIndex = 0
// 切换轮播图
switchBanner()
}7. 离开浏览器窗口时,清除定时器
Click me to view the code js
js
// window的焦点(离开浏览器窗口时,清除定时器)
document.onvisibilitychange = function () {
// 如果离开当前浏览器页面,清除定时器; 如果在当前浏览器页面,开启定时器;
if (this.visibilityState === "hidden") {
stopTime()
} else if (this.visibilityState === "visible") {
startTime()
}
}25. 华为商城的轮播图(无限轮播图)

无限滚动
Click me to view the code js
js
// 8.无限轮播图
var firstItemEl = imagesEl.children[0].cloneNode(true)
var lastItemEl = imagesEl.children[bannersCount - 1].cloneNode(true)
imagesEl.append(firstItemEl)
imagesEl.prepend(lastItemEl)
// 位置调整
firstItemEl.style.left = `${bannersCount * 100}%`
lastItemEl.style.left = "-100%"
...
// 对功能封装的函数
// 封装函数: 切换轮播图
function switchBanner() {
// 1.切换整个imagesEl的transform
....
if (currentIndex === bannersCount) {
currentIndex = 0
setTimeout(function () {
// imagesEl.style.transform = "translateX(0)"
// 等价于👆🏻注释代码
imagesEl.style.transform = `translateX(${-currentIndex * 100}%)`
imagesEl.style.transition = "none"
}, animationDuration)
} else if (currentIndex === -1) {
currentIndex = bannersCount - 1
setTimeout(function () {
// imagesEl.style.transform = `translateX(${-(bannersCount - 1) * 100}%)`
// 等价于👆🏻注释代码
imagesEl.style.transform = `translateX(${-currentIndex * 100}%)`
imagesEl.style.transition = "none"
}, animationDuration)
}
// 2.切换指示器(小圆点)的item
...
}代码重构
Click me to view the code js
js
...
// 封装函数: 切换轮播图
function switchBanner() {
// 1.图片自动轮播
...
if (currentIndex === bannersCount) {
currentIndex = 0
// 修正位移的位置
fixBannerPosition()
} else if (currentIndex === -1) {
currentIndex = bannersCount - 1
// 修正位移的位置
fixBannerPosition()
}
// 2.指示器(小圆点)轮播
...
}
...
// 封装函数: 修正位移的位置
function fixBannerPosition() {
setTimeout(function () {
imagesEl.style.transform = `translateX(${-currentIndex * 100}%)`
imagesEl.style.transition = "none"
}, animationDuration)
}
...
coderccb