<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<style>
.carousel{
width: 600px;
height: 300px;
border:1px solid #000;
position:relative;
overflow: hidden;
margin:50px auto;
}
.carousel ul,.carousel ol{
list-style: none;
padding: 0;
margin: 0;
}
.carousel ul{
height: 300px;
position:absolute;
left:0;
top:0;
}
.carousel ul li{
float:left;
width: 600px;
height: 300px;
}
.carousel ul li a img{
width: 600px;
height: 300px;
}
.carousel ol{
height: 20px;
border-radius: 10px;
background-color:rgba(255,255,255,.7);
position: absolute;
bottom:10px;
left: 50%;
transform: translateX(-50%);
}
.carousel ol li{
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #000;
float:left;
margin: 5px;
}
.carousel:hover{
cursor: pointer;
}
.carousel>a{
width: 20px;
height: 40px;
color:#fff;
background-color:rgba(0,0,0,.7);
text-align: center;
line-height: 40px;
position:absolute;
top:50%;
transform: translateY(-50%);
text-decoration: none;
}
.carousel>a.leftBtn{
left: 0;
}
.carousel>a.rightBtn{
right: 0;
}
</style>
<body>
<div class="carousel">
<ul>
</ul>
<ol>
</ol>
<a href="javascript:;" class="leftBtn"><</a>
<a href="javascript:;" class="rightBtn">></a>
</div>
</body>
<script src =" https://code.jquery.com/jquery-3.6.0.min.js "></script>
<script src="./js/utils.js"></script>
<script>
// 定义放图片的数组
var arr = ['./images/1.jfif', './images/2.webp', './images/3.jfif']
// 根据数组创建li
arr.forEach(item => {
$(`
<li>
<a href="">
<img src="${item}" />
</a>
</li>
`).appendTo($('.carousel ul'))
$('<li></li>').appendTo($('.carousel ol'))
})
// 给第一个ol下的li添加红色背景
$('.carousel ol li').first().css('backgroundColor', 'red')
// 将ul的第一个和最后一个复制放在后面和前面
var $first = $('.carousel ul li').first().clone()
// 给ul的最前面放最后一个复制品
$('.carousel ul').prepend($('.carousel ul li').last().clone())
// 将$first放在ul的末尾
$first.appendTo($('.carousel ul'))
// 设置ul的宽度
$('.carousel ul').width($('.carousel ul').children().length * $first.outerWidth(true))
// 设置ul的left
$('.carousel ul').css('left', -$first.outerWidth(true) + 'px')
// 定义当前显示的li的下标
var index = 1
// 定义开关
var flag = true
// 定义定时器变量
var timer
// 右箭头点击轮播
$('.carousel').on('click', 'a.rightBtn', function(){
// 如果开关是关闭状态,无效果
if(!flag) return false
// 一旦开始走了,就关上开关
flag = false
// 下标自增
index++
// 让ul轮播
animate($('.carousel ul')[0], {
left: -index * $first.outerWidth(true)
}, function(){
// 判断index的最大值
if(index === $('.carousel ul li').length - 1){
index = 1
// 秒切
$('.carousel ul').css('left', -index * $first.outerWidth(true) + 'px')
}
// 设置小圆点
$('.carousel ol li').eq(index-1).css('backgroundColor', 'red').siblings().css('backgroundColor', '#000')
// 开关打开
flag = true
})
})
// 左箭头
$('.carousel>a.leftBtn').click(function(){
if(!flag) return false
flag = false
index--
animate($('.carousel ul')[0], {
left: -index * $first.outerWidth(true)
}, function(){
if(index === 0){
index = $('.carousel ul li').length - 2
$('.carousel ul').css('left', -index * $first.outerWidth(true) + 'px')
}
// 设置小圆点
$('.carousel ol li').eq(index-1).css('backgroundColor', 'red').siblings().css('backgroundColor', '#000')
flag = true
})
})
// 小圆点点击
$('.carousel ol li').click(function(){
if(!flag) return false
flag = false
index = $(this).index() + 1
animate($('.carousel ul')[0], {
left: -index * $first.outerWidth(true)
}, function(){
if(index === 0){
index = $('.carousel ul li').length - 2
$('.carousel ul').css('left', -index * $first.outerWidth(true) + 'px')
}
// 设置小圆点
$('.carousel ol li').eq(index-1).css('backgroundColor', 'red').siblings().css('backgroundColor', '#000')
flag = true
})
})
// 自动轮播
timer = setInterval(function(){
$('.carousel>a.rightBtn').trigger('click')
}, 1000)
// 移入移出
$('.carousel').hover(function(){
clearInterval(timer)
}, function(){
timer = setInterval(function(){
$('.carousel>a.rightBtn').trigger('click')
}, 1000)
})
</script>
</html>
/**
* 获取随机数的函数
* @param {number} a 代表范围的数字
* @param {number} b 代表范围的数字
* @return {number} 返回范围内的随机整数
*/
function getRandom(a, b){
return Math.floor(Math.random() * Math.abs(a - b)) + Math.min(a, b)
}
/**
* 获取16进制的随机颜色值
*/
function getColor(){
var color = '#'
for(var i=0;i<3;i++){
var hex = getRandom(0, 256).toString(16)
color += hex.length === 1 ? '0' + hex : hex;
}
return color
}
/**
* 批量设置样式的函数
* @param {node} ele 被设置样式的标签对象
* @param {object} styleObj 要设置的样式组成的键值对
*/
function setStyle(ele, styleObj){
for(var key in styleObj){
ele.style[key] = styleObj[key]
}
}
/**
* 进行动画的函数
* @param {node} ele 要进行动画的元素
* @param {object} obj 动画的属性和值组成的键值对
* @param {function} fn 动画结束后要执行的函数
*/
function animate(ele, obj, fn){
var k = 0
for(var key in obj){
k++
(function(key){
var currentStyle = getComputedStyle(ele)[key]
var target = obj[key]
if(key === 'opacity'){
currentStyle *= 100
target *= 100
}
currentStyle = parseInt(currentStyle)
var timerId = setInterval(function(){
var speed = (target - currentStyle) / 20
currentStyle += speed > 0 ? Math.ceil(speed) : Math.floor(speed)
if(key === 'opacity') ele.style[key] = currentStyle / 100
else ele.style[key] = currentStyle + 'px'
if(currentStyle === target){
clearInterval(timerId)
if(--k === 0) fn()
}
}, 20)
})(key)
}
}
/**
* 获取cookie的函数
* @param {string} key 要获取的cookie的键
* @returns key对应的值
*/
function getCookie(key){
var cookie = document.cookie;
var arr = cookie.split('; ')
for(var i=0;i<arr.length;i++){
var brr = arr[i].split('=')
if(brr[0] === key){
return brr[1]
}
}
}
/**
* 设置cookie的函数
* @param {string} key 要设置的cookie的键
* @param {string} value key对应的值
* @param {number} seconds 有效的秒
*/
function setCookie(key, value, seconds){
var date = new Date()
date.setTime(date.getTime()+seconds*1000-8*3600*1000)
document.cookie = key + '='+value+';expires='+date
}
/**
* 删除cookie的函数
* @param {string} key 要删除的cookie的键
*/
function removeCookie(key){
setCookie(key, null, -1)
}
/**
* 发送ajax请求的函数
* @param {object} obj 发送ajax的配置项
* @returns undefined
*/
function ajax(obj){
if(obj.url === undefined) throw new Error('请求地址不能为空')
if(Object.prototype.toString.call(obj.url) != '[object String]') throw new Error('请求地址错误')
if(obj.method === undefined) obj.method = 'get'
if(obj.method.toLowerCase() != 'get' && obj.method.toLowerCase() != 'post') throw new Error('请求方式只能是get或post')
if(obj.isAsync === undefined) obj.isAsync = true
if(Object.prototype.toString.call(obj.isAsync) != '[object Boolean]') throw new Error('isAsync必须是布尔值')
if(!obj.data) obj.data = null
if(obj.success === undefined) obj.success = function(){}
if(Object.prototype.toString.call(obj.success) != '[object Function]') throw new Error('success必须是函数')
if(obj.error === undefined) obj.error = function(){}
if(Object.prototype.toString.call(obj.error) != '[object Function]') throw new Error('error必须是函数')
var data = ''
if(obj.data != undefined){
if(Object.prototype.toString.call(obj.data) === '[object String]'){
if(!obj.data.includes('=')) throw new Error('data数据是非法的!')
data = obj.data
}else if(Object.prototype.toString.call(obj.data) === '[object Object]'){
var arr = []
for(var key in obj.data){
arr.push(key + '=' + obj.data[key])
}
data = arr.join('&')
}else throw new Error('data必须是字符串或对象')
if(obj.method.toLowerCase() === 'get') obj.url += '?' + data
}
if(obj.dataType === undefined) obj.dataType = 'json'
if(obj.dataType.toLowerCase() != 'json' && obj.dataType.toLowerCase() != 'xml' && obj.dataType.toLowerCase() != 'text') throw new Error('dataType只接受json、text、xml')
var xhr = new XMLHttpRequest;
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status>=200 && xhr.status<300){
var res = '';
switch(obj.dataType.toLowerCase()){
case 'json':
res = xhr.responseText
res = JSON.parse(res)
break;
case 'xml':
res = xhr.responseXML
break;
case 'text':
res = xhr.responseText
break;
}
obj.success(res)
}else obj.error()
}
}
xhr.open(obj.method, obj.url, obj.isAsync);
if(obj.method.toLowerCase() === 'post' && data){
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
xhr.send(data)
return
}
xhr.send()
}
/// 调用模板 //
/*
ajax({
url: '', // 请求地址 - 必填项
method: '', // 请求方式 - 可选项,默认get
data: '', // 请求主体 - 可选项 - 允许字符串/object
isAsync: true, // 是否异步 - 可选项 - 默认true
dataType: 'json', // 希望返回的数据格式 - 可选项 - 默认json - 允许json/xml/text
success: res => {}, // 请求成功后要执行的函数 - 可选项 - 默认是一个匿名函数 - 会将请求回来的数据放在函数中作为参数
error: function(){} // 请求失败会执行的函数 - 可选项 - 默认是一个匿名函数
})
*/
/**
* 发送ajax请求的函数
* @param {object} obj 发送ajax的配置项
* @returns undefined
*/
function ajaxPromise(obj){
return new Promise(function(resolve, reject){
if(obj.url === undefined) throw new Error('请求地址不能为空')
if(Object.prototype.toString.call(obj.url) != '[object String]') throw new Error('请求地址错误')
if(obj.method === undefined) obj.method = 'get'
if(obj.method.toLowerCase() != 'get' && obj.method.toLowerCase() != 'post') throw new Error('请求方式只能是get或post')
if(obj.isAsync === undefined) obj.isAsync = true
if(Object.prototype.toString.call(obj.isAsync) != '[object Boolean]') throw new Error('isAsync必须是布尔值')
if(!obj.data) obj.data = null
var data = ''
if(obj.data != undefined){
if(Object.prototype.toString.call(obj.data) === '[object String]'){
if(!obj.data.includes('=')) throw new Error('data数据是非法的!')
data = obj.data
}else if(Object.prototype.toString.call(obj.data) === '[object Object]'){
var arr = []
for(var key in obj.data){
arr.push(key + '=' + obj.data[key])
}
data = arr.join('&')
}else throw new Error('data必须是字符串或对象')
if(obj.method.toLowerCase() === 'get') obj.url += '?' + data
}
if(obj.dataType === undefined) obj.dataType = 'json'
if(obj.dataType.toLowerCase() != 'json' && obj.dataType.toLowerCase() != 'xml' && obj.dataType.toLowerCase() != 'text') throw new Error('dataType只接受json、text、xml')
var xhr = new XMLHttpRequest;
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status>=200 && xhr.status<300){
var res = '';
switch(obj.dataType.toLowerCase()){
case 'json':
res = xhr.responseText
res = JSON.parse(res)
break;
case 'xml':
res = xhr.responseXML
break;
case 'text':
res = xhr.responseText
break;
}
resolve(res)
}else reject()
}
}
xhr.open(obj.method, obj.url, obj.isAsync);
if(obj.method.toLowerCase() === 'post' && data){
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
xhr.send(data)
return
}
xhr.send()
})
}
/// 调用模板 //
/*
ajaxPromise({
url: '', // 请求地址 - 必填项
method: '', // 请求方式 - 可选项,默认get
data: '', // 请求主体 - 可选项 - 允许字符串/object
isAsync: true, // 是否异步 - 可选项 - 默认true
dataType: 'json', // 希望返回的数据格式 - 可选项 - 默认json - 允许json/xml/text
})
*/