目录
前言
开篇语
准备工作
需求
HTML和CSS
注意事项
原生JS实现
变量设置
方法设置
自动轮播与轮播销毁
翻页按钮
li点击切换指定图片
JQuery实现
变量设置
方法设置
自动轮播与轮播销毁
翻页按钮
li点击切换指定图片
结束语
前言
开篇语
本系列为短章节,单独讲述部分特殊重点案例,本期讲述JS轮播图的原生JS实现和JQuery实现。
与HTML和CSS相比,JS加入了很多逻辑性的元素在里面,所以需要一定的逻辑思维能力,要求能够整合一些知识。如果遇到不理解之处,可以参阅同系列之前的章节。
准备工作
软件:【参考版本】Visual Studio Code
插件(扩展包):Open in browser, Live Preview, Live Server, Tencent Cloud AI Code Assistant, htmltagwrap
提示:在不熟练的阶段建议关闭AI助手
第三方JS库:jquery.min.js
提示:请站内搜索下载、引入方式
浏览器版本:Chrome
系统版本: Win10/11/其他非Windows版本
需求
本次的需求为实现轮播图的效果,要求使用原生JS和JQuery两种方式实现。
示例效果如下——
详细要求如下——
- 点击下方圆点,可以实现圆点高亮,并且切换对应图片;
- 点击左右箭头,可以实现轮播图的左右切换;
- 鼠标移入轮播图,轮播图停止播放,移除时恢复。
HTML和CSS
按照惯例,在学习JS时我将把无关的HTML和CSS放在这里,仅供参考。
参考HTML代码——
<header>头部</header>
<nav>导航</nav>
<main>
<section id="banner" class="w1200">
<div id="bn-left" class="bn-btn"></div>
<div id="bn-right" class="bn-btn"></div>
<div id="bn-pic"></div>
<ul id="bn-points">
<li class="active"></li>
<li class=""></li>
<li class=""></li>
<li class=""></li>
<li class=""></li>
<li class=""></li>
</ul>
</section>
<article class="w1200">内容</article>
</main>
<footer>底部</footer>
参考CSS代码——
* {
margin: 0;
padding: 0;
list-style: none;
text-decoration: none;
box-sizing: border-box;
text-align: center;
font-size: 30px;
}
body {
min-width: 1500px;
}
.w1200 {
width: 1200px;
margin: 0 auto;
}
header {
height: 50px;
background: #ef8080;
}
nav {
height: 50px;
background: #e6af7e;
}
main {
background: #7ed3e6;
}
#banner {
height: 300px;
position: relative;
background: #7ea1e6;
}
#banner .bn-btn {
width: 40px;
height: 80px;
position: absolute;
top: 50%;
transform: translateY(-50%);
background: #00000077;
background-position: center;
background-size: contain;
background-repeat: no-repeat;
cursor: pointer;
}
#banner #bn-left {
/* 左侧翻页按钮箭头图(需自备) */
background-image: url("../images/zjt.png");
left: 0;
}
#banner #bn-right {
/* 右侧翻页按钮箭头图(需自备) */
background-image: url("../images/yjt.png");
right: 0;
}
#banner #bn-pic {
width: 100%;
height: 100%;
/* 进入页面默认显示第一张图 */
background-image: url("../images/11.png");
background-position: center;
background-size: cover;
background-repeat: no-repeat;
}
#banner #bn-points {
width: 160px;
display: flex;
justify-content: space-between;
position: absolute;
bottom: 30px;
left: 50%;
transform: translateX(-50%);
}
#banner #bn-points li {
width: 20px;
height: 20px;
border-radius: 50%;
background: #ffffffbb;
cursor: pointer;
}
#banner #bn-points li.active {
background: #db1a1abb;
}
article {
height: 2000px;
background: #e67eb4;
}
footer {
height: 50px;
position: fixed;
right: 0;
bottom: 0;
left: 0;
background: #e6e47e;
}
注意事项
左右侧的箭头需要自行寻找图片,可以在阿里巴巴矢量图标库中查找。
需要自备6张图片,命名为11.png~66.png,后续可以根据自己的需要修改JS代码。
或者可以在JS中设置一个数组,用来存储各图片的名称,后续用数组名加索引获取即可。
原生JS实现
变量设置
首先,获取轮播图的各组件的DOM元素——
var banner = document.querySelector('#banner')
var bnl = document.querySelector('#bn-left')
var bnr = document.querySelector('#bn-right')
var pic = document.querySelector('#bn-pic')
var points = document.querySelector('#bn-points')
var lis = points.querySelectorAll('li')
接下来,我们需要三个全局变量,分别用于记录当前的索引index(可以同步图片索引和 li 索引)、图片数量len(底部 li 数量)和时间变量timer(用于记住轮播图使用的setInterval)。
var index = 0
var len = lis.length
var timer = null
方法设置
分析案例,以是否自动进行作为依据划分,应当分为轮播操作和用户操作。
首先是轮播效果,在用户不进行任何操作时,自动进行循环播放图片,并切换底部 li 样式。
我们可以把“自动循环”和“切换图片、样式”分别封装为两个方法,便于我们在需要时调用。
图片和 li 共用index,以实现预期的同步效果。
在自动循环的方法setTimer()中,将setInterval赋值给全局的时间变量,在其回调函数中,设置index每隔1s(1000ms)自增一次,并在到达右侧边界时重新跳转回初始位置。当index发生改变之后,更新当前的图片和 li 高亮位置。
在切换图片、样式的方法change()中,利用图文公用的index换算出当前的图片地址和需要设置高亮的li(利用排他算法,在JS入门(八)章节中详述)。
两个方法的参考代码如下——
// 自动轮播方法
function setTimer() {
timer = setInterval(function () {
index++
if (index == len) index = 0
change()
}, 1000)
}
// 图片切换和样式设置
function change() {
var num = (parseInt(index) + 1) * 11
pic.style.backgroundImage = `url('./images/${num}.png')`
for (let i = 0; i < len; i++) {
lis[i].className = ""
}
lis[index].className = "active"
}
自动轮播与轮播销毁
在未进行操作的情况下,我们需要让图片自动轮播,所以直接调用setTimer()设置轮播计时器。
setTimer()
接下来,我们需要让鼠标移入轮播图时,自动轮播停止,否则用户的翻页指令可能会与自动轮播的效果发生冲突。
为此,我们可以在移入轮播图区域时删除计时器(利用时间变量timer),并在鼠标移出时恢复计时器。
为轮播图区域添加上述的两个事件——
// 设置鼠标移入banner图片停止移动和鼠标移出图片继续移动
banner.addEventListener('mouseenter', function(){
clearInterval(timer)
})
banner.addEventListener('mouseleave', function(){
setTimer()
})
翻页按钮
在点击左右两侧的分页按钮时,我们需要实现让轮播图向前或向后翻页一次的效果。
为此,我们可以利用全局变量index的自减和自增,再重新调用change()方法,实现翻页的效果。
注意,在index自增自减超出边界值时,我们需要设置index值为另一侧边界值。
// 左右按钮点击切换轮播图
bnl.addEventListener("click", function () {
index--
if (index == -1) index = 5
change()
})
bnr.addEventListener("click", function () {
index++
if (index == 6) index = 0
change()
})
li点击切换指定图片
在这一步中,我们需要遍历lis,为底部的所有li绑定点击事件,并且获取到当前li的索引值赋值给全局index,最后调用change()实现切换操作。
但是,之前我们说过,在遍历绑定事件之后,for-i循环中的计数器i已经超出最大值,此时如果直接使用lis[i]来获取索引,将会出现溢出错误。
为此,在原生JS中我们可以使用自定义属性data-index来,在绑定事件之前记录当前li的索引值(见JS入门(八))。
// 添加属性,并设置points激活和背景改变
for (var i = 0; i < lis.length; i++) {
lis[i].setAttribute("data-index", i)
lis[i].onclick = function () {
index = this.dataset.index
change()
}
}
到此,我们已经实现最基本的轮播图的全部功能。
JQuery实现
变量设置
在使用JQuery方式时,我们直接使用$()包装原生DOM即可 ,随写随用。
但是,我们基本的三个全局变量还是得有的——
var index = 0
var len = $('li').length
var timer = null
这里的$('li')具有隐式迭代,可以直接获取li的总数量。
方法设置
JQuery的本质还是对原生的DOM进行操作,因此步骤上实际上还是与原生操作相同,但是JQuery为我们提供了更简洁的方式。
setTimer()与原生DOM无差别。
change()中,设置背景图片使用css()设置background-image方式(注意驼峰命名),排他操作使用链式编程排他操作(见JS进阶(一)),利用eq(index)筛选index位置处的li。
// 设置计时器方法
function setTimer() {
timer = setInterval(function () {
if (index == len) index = 0
change()
index++
}, 1000)
}
// 图片设置方法
function change() {
$('#bn-pic').css({
backgroundImage: `url('./images/${(index + 1) * 11}.png')`
})
$('li').eq(index).addClass('active').siblings().removeClass('active')
}
自动轮播与轮播销毁
进入页面,自动轮播。
setTimer()
使用on为轮播图盒子绑定移入销毁计时器和移除重新恢复计时器的事件——
// 设置鼠标移入banner图片停止移动和鼠标移出图片继续移动
$('#banner').on('mouseenter', function () {
clearInterval(timer)
})
$('#banner').on('mouseleave', function () {
setTimer()
})
翻页按钮
使用on为翻页按钮绑定前后翻页事件,当然这里的翻页按钮不需要再绑定其他事件,所以使用click()也是可以的。
// 左右按钮点击切换轮播图
$('#bn-left').on("click", function () {
index--
if (index == -1) index = 5
change()
})
$('#bn-right').on("click", function () {
index++
if (index == 6) index = 0
change()
})
li点击切换指定图片
li使用事件委托,委托父级ul执行冒泡事件获取当前的点击的li,进一步获取其索引值赋值给全局index,最后使用change()方法实现切换。
注意,原生事件对象e在获取其原生DOM元素e.target后,需要使用$()包装,以便调用index()。
由于JQuery有内置的隐式迭代和对应的index()方法,所以我们不需要再设置额外的data-index了。
// 设置points激活和背景改变
$('ul').on({
'click'(e) {
index = $(e.target).index()
change()
}
}, 'li')
结束语
本期的内容到这里就结束了,在后续的本系列博客中,我会继续更新js的特殊重点案例。
在全栈领域,博主也只不过是一个普通的萌新而已。本系列的博客主要是记录一下自己学习的一些经历,然后把自己领悟到的一些东西总结一下,分享给大家。
文章全篇的操作过程都是笔者亲自操作完成的,一些定义性的文字加入了笔者自己的很多理解在里面,所以仅供参考。如果有说的不对的地方,还请谅解。
==期待与你在下一期博客中再次相遇==
——还在漏气的【H2O2】