- 轮播图原理:给图片一个数字属性,播放下一张图片只要数字 + 1 即可实现;最后一张图片的处理方式是求余操作(求余操作能让小标回到0)
<!-- data-imgs 是图片的总数 --> <!-- data-active 是当前显示的图片的下标 --> <!-- 我们要播放图片只需要获取data-active属性即可,比如打开图片:e("#id-image-" + "data-active") --> <div class="slide" data-imgs="3" data-active="0"> <!-- active属性:显示图片 --> <img id="id-image-0" class="slide-image active" src="picture/1.jpg" alt=""> <img id="id-image-1" class="slide-image" src="picture/2.jpg" alt=""> <img id="id-image-2" class="slide-image" src="picture/3.jpg" alt="">
- 自动播放原理:利用setInterval(function, time)和setTimeout(function, time)实现:
- setInterval(function, time):定时器
1. 函数含义:隔time时长,重复执行function函数,无限循环执行
2. function:执行函数的函数名
3. time:间隔时间,以毫秒为单位,1s = 1000ms
4. 注意:setInterval() 会返回一个数字, 这个数字可以用来清除定时器
5. 清除格式:clearInterval()
- setInterval(function, time):定时器
- setTimeout(function, time):定时器
1. 函数含义:隔time时长,重复执行function函数,只执行一次
2. function:执行函数的函数名
3. time:间隔时间
4. 注意:setTimeout() 会返回一个数字, 这个数字可以用来清除定时器
5. 清除格式:clearTimeout()// 设置轮播图 const autoPlay = function() { let interval = 2000 setInterval(function() { // 每 2s 都会调用这个函数 // 该函数会播放下一张图片 playNextImage() }, interval) }
源代码(图片文件夹需要自建)html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>轮播图</title>
<style>
.hide {
display: none;
}
.menu-content {
height: 100px;
border: 1px solid red;
}
.item {
filter: grayscale(100%);
}
.item.highlight {
filter: initial;
}
.item.highlight img {
width: 150px;
height: 150px;
}
img {
/*transition 这个 css 指定了某个属性发生变化的时候自动使用动画效果和动画时间*/
transition: width 1s, height 1s;
}
.item img {
width: 100px;
height: 100px;
}
.slide {
position: relative;
width: 600px;
}
.slide-image {
display: none;
max-width: 100%;
}
.active {
display: inline-block;
}
.slide-button {
width: 30px;
height: 50px;
color: #fff;
border: 0;
background: #000;
opacity: 0.3;
cursor: pointer;
outline: 0;
}
.slide-button.left {
left: 0;
}
.slide-button.right {
right: 0;
}
/* 垂直居中 */
.vertical-center {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
/* 水平居中 */
.horizontal-center {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
.slide-indicators {
bottom: 10px;
width: 150px;
margin: 0 auto;
text-align: center;
}
.slide-indi {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
background: red;
}
.white {
background: white;
}
</style>
</head>
<body>
<!-- 轮播图 -->
<div class="lunbotu">
<!-- data-imgs 是图片的总数 -->
<!-- data-active 是当前显示的图片的下标 -->
<!-- 我们要播放图片只需要获取data-active属性即可,比如打开图片:e("#id-image-" + "data-active") -->
<div class="slide" data-imgs="3" data-active="0">
<!-- active属性:显示图片 -->
<img id="id-image-0" class="slide-image active" src="picture/1.jpg" alt="">
<img id="id-image-1" class="slide-image" src="picture/2.jpg" alt="">
<img id="id-image-2" class="slide-image" src="picture/3.jpg" alt="">
<!-- html entry(实体) -->
<!-- <:< -->
<!-- >:> -->
<button class="slide-button left vertical-center" data-offset="-1"><</button>
<button class="slide-button right vertical-center" data-offset="1">></button>
<!-- 设置小圆点-->
<div class="slide-indicators horizontal-center">
<!-- white属性:表示小圆点颜色为白色(默认为红色) -->
<div id="id-indicator-0" class="slide-indi white" data-index="0"></div>
<div id="id-indicator-1" class="slide-indi" data-index="1"></div>
<div id="id-indicator-2" class="slide-indi" data-index="2"></div>
</div>
</div>
</div>
<script src="milu.js"></script>
<script src="ex.js"></script>
</body>
</html>
milu.js:
// 输出函数log
const log = console.log.bind(console)
// condition表示的是一个Boolean值,message是一个字符串
// 测试函数
const ensure = function(condition, message) {
// 在条件不成立的时候, 输出 message
if (!condition) {
log('*** 测试失败', message)
} else {
log('*** 测试成功')
}
}
// 在全局打开第一个具有selector属性的选择器
// selector是元素选择器,可以是class选择器,也可以是id选择器,还可以是元素选择器
// 如果找到元素,则返回该元素,否则返回null并且提出一个警告
const e = function(selector) {
let element = document.querySelector(selector)
if (element === null) {
let s = `selector ${selector} not found`
alert(s)
//
return null
} else {
return element
}
}
// 在全局内返回所有具有selector属性的元素,且该返回值是一个数组
// selector是元素选择器,可以是class选择器,也可以是id选择器,还可以是元素选择器
// 如果找到元素,则返回该元素,否则返回null并且提出一个警告
const es = function(selector) {
let elements = document.querySelectorAll(selector)
if (elements.length === 0) {
let s = `selector ${selector} not found`
alert(s)
//
return []
} else {
return elements
}
}
// selector元素的属性
// eventName是时间的名字
// callback是一个函数
// 该函数是把带有selector元素绑定一个事件callback,且该事件的触发函数是eventName
const bindAll = function(selector, eventName, callback) {
let elements = es(selector)
for (let i = 0; i < elements.length; i++) {
let tag = elements[i]
// log(tag)
tag.addEventListener(eventName, callback)
}
}
// element是一个元素选择器,表示某一个元素
// html是要添加的元素,其类型是html字符串
// 该函数表示将html元素添加到element元素的最末端
const appendHtml = function(element, html) {
element.insertAdjacentHTML('beforeend', html)
}
// element是一个元素选择器,表示一个元素
// eventName表示响应事件
// callback表示响应函数
// 该函数表示给element元素添加一个响应事件,响应的类型为eventName,响应函数为callback
const bindEvent = function(element, eventName, callback) {
element.addEventListener(eventName, callback)
}
// class表示一个class属性
// 该函数表示移除全局所有带有className属性的元素的class属性
const removeClassAll = function(className) {
let selector = '.' + className
let elements = es(selector)
for (let i = 0; i < elements.length; i++) {
let e = elements[i]
log('classname', className, e)
e.classList.remove(className)
}
}
// element表示是一个元素选择器,表示一个元素
// selector是一个元素的属性
// 在element元素中,打开带有selector属性的元素
const find = function(element, selector) {
let e = element.querySelector(selector)
if (e === null) {
let s = `元素没找到,选择器 ${selector} 没有找到或者 js 没有放在 body 里`
alert(s)
return null
} else {
return e
}
}
ex.js:
const showIndicatorAtIndex = function(index) {
let nextIndex = index
// 切换小圆点
// 1. 删除当前小圆点的 class
let indicatorClass = 'white'
removeClassAll(indicatorClass)
// 2. 得到下一个小圆点的选择器
let indicatorSelector = '#id-indicator-' + String(nextIndex)
let indicator = e(indicatorSelector)
indicator.classList.add(indicatorClass)
}
// 显示对应的小圆点
const showImageAtIndex = function(slide, index) {
log('index', index)
let nextIndex = index
// 设置父节点的 data-active
slide.dataset.active = nextIndex
log('nextIndex', nextIndex)
let nextSelector = '#id-image-' + String(nextIndex)
// 删除当前图片的 class 给下一张图片加上 class
let className = 'active'
removeClassAll(className)
let img = e(nextSelector)
img.classList.add(className)
// 显示小圆点
showIndicatorAtIndex(nextIndex)
}
// 求出下一张图片的坐标
const nextIndex = function(slide, offset) {
let numberOfImgs = parseInt(slide.dataset.imgs, 10)
let activeIndex = parseInt(slide.dataset.active, 10)
// log('click slide')
// 求出 button 的 data-offset
// 上一张按钮的 offset 是 1
// 下一张按钮的 offset 是 -1
// let offset = Number(button.dataset.offset)
// 求出下一张图片的 id
let i = (activeIndex + offset) % numberOfImgs
return i
}
// 给按钮绑定事件
const bindEventSlide = function() {
// 打开button
let selector = '.slide-button'
bindAll(selector, 'click', function(event) {
log('click next')
// 找到 slide div
let button = event.target
let slide = button.parentElement
// log('slide 哈哈', slide)
let offset = Number(button.dataset.offset)
// 求出下一个图片的 index
let index = nextIndex(slide, offset)
// 显示下一张图片
showImageAtIndex(slide, index)
})
}
// 给小圆点绑定事件
const bindEventIndicator = function() {
let selector = '.slide-indi'
bindAll(selector, 'click', function(event) {
log('indicator')
let self = event.target
let index = Number(self.dataset.index)
log('index', index, typeof index)
// 得到 slide
let slide = self.closest('.slide')
// 直接播放第 n 张图片
showImageAtIndex(slide, index)
})
}
// 自动播放函数
const playNextImage = function() {
let slide = e('.slide')
// 求出下一个图片的 index
let index = nextIndex(slide, 1)
log('index in next', index)
// 显示下一张图片
showImageAtIndex(slide, index)
}
// 完成对按钮和小圆点元素的事件绑定
const bindEvents = function() {
bindEventSlide()
bindEventIndicator()
}
// 设置轮播图
const autoPlay = function() {
let interval = 2000
setInterval(function() {
// 每 2s 都会调用这个函数
playNextImage()
}, interval)
}
const __main = function() {
// 设置左右按钮,并完成事件绑定
bindEvents()
// 设置自动播放
autoPlay()
}
__main()