滑动轮播图


<!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{
    width: 3000px;
    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 ol li.active{
    background-color: #f00;
}
.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>
        <li>
            <a href="">
                <img src="./images/1.jfif" alt="">
            </a>
        </li>
        <li>
            <a href="">
                <img src="./images/2.webp" alt="">
            </a>
        </li>
        <li>
            <a href="">
                <img src="./images/3.jfif" alt="">
            </a>
        </li>
    </ul>
    <ol>
        <li class="active"></li>
        <li></li>
        <li></li>
    </ol>
    <a href="javascript:;" class="leftBtn">&lt;</a>
    <a href="javascript:;" class="rightBtn">&gt;</a>
</div>
</body>
<script src="./js/utils.js"></script>
<script>
// 1.获取元素
// 2.给ul的前后各复制一个li
// 3.调整ul的left值
// 4.开始轮播图效果 - 都是在操作下标 - 从右箭头点击开始
var ul = document.querySelector('.carousel ul');
// 复制
var firstLi = ul.firstElementChild.cloneNode(true)
// console.log(firstLi);
var lastLi = ul.lastElementChild.cloneNode(true)
// 分别放在末尾和最前面
ul.appendChild(firstLi)
ul.insertBefore(lastLi, ul.firstElementChild)
// 调整left
ul.style.left = -firstLi.offsetWidth + 'px'

// 获取ol
var ol = document.querySelector('.carousel ol');
// 定义下标
var index = 1
// 定义开关
var flag = true
// 右箭头点击
var rightBtn = document.querySelector('.carousel>a.rightBtn');
rightBtn.onclick = function(){
    // 判断开关
    if(!flag) return false
    // 动画开始 - 开关关闭
    flag = false
    // 操作下标
    index++;
    // 让ul开始动画
    animate(ul, {
        left: -index * firstLi.offsetWidth
    }, function(){
        // 限制index 的最大值
        if(index === ul.children.length-1){
            index = 1
            ul.style.left = -index * firstLi.offsetWidth + 'px'
            console.log(-index * firstLi.offsetWidth);
        }
        // 动画结束后
        // 操作小圆点
        // 将所有小圆点的active去掉
        for(var i=0;i<ol.children.length;i++){
            ol.children[i].className = ''
        }
        // 给当前对应的小圆点添加active
        ol.children[index-1].className = 'active'
        // 动画结束 - 打开开关
        flag = true
    })
}

// 左箭头点击
var leftBtn = document.querySelector('.carousel>a.leftBtn');
leftBtn.onclick = function(){
    if(!flag) return false
    flag = false
    // 操作下标
    index--;
    // 让ul开始动画
    animate(ul, {
        left: -index * firstLi.offsetWidth
    }, function(){
        // 限制index 的最大值
        if(index === 0){
            index = ul.children.length-2
            ul.style.left = -index * firstLi.offsetWidth + 'px'
            console.log(-index * firstLi.offsetWidth);
        }
        // 动画结束后
        // 操作小圆点
        // 将所有小圆点的active去掉
        for(var i=0;i<ol.children.length;i++){
            ol.children[i].className = ''
        }
        // 给当前对应的小圆点添加active
        ol.children[index-1].className = 'active'
        flag = true
    })
}

// 小圆点点击
for(var j=0;j<ol.children.length;j++){
    (function(j){
        ol.children[j].onclick = function(){
            if(!flag) return false
            flag = false
            index = j+1
            animate(ul, {
                left: -index * firstLi.offsetWidth
            }, function(){
                // 限制index 的最大值
                if(index === 0){
                    index = ul.children.length-2
                    ul.style.left = -index * firstLi.offsetWidth + 'px'
                    console.log(-index * firstLi.offsetWidth);
                }
                // 动画结束后
                // 操作小圆点
                // 将所有小圆点的active去掉
                for(var i=0;i<ol.children.length;i++){
                    ol.children[i].className = ''
                }
                // 给当前对应的小圆点添加active
                ol.children[index-1].className = 'active'
                flag = true
            })
        }
    })(j)
}

// 自动轮播
var timerId = setInterval(function(){
    rightBtn.onclick()
}, 500)

// 大盒子的移入移出
var carousel = document.querySelector('.carousel');
carousel.onmouseover = function(){
    clearInterval(timerId)
}

carousel.onmouseout = function(){
    timerId = setInterval(function(){
        rightBtn.onclick()
    }, 500)
}
</script>
</html>
/**
 * 进行动画的函数
 * @param {node} ele 要进行动画的元素
 * @param {object} obj 动画的属性和值组成的键值对
 * @param {function} fn 动画结束后要执行的函数
 */
function animate(ele, obj, fn){ 
    // 定义计数器 - 计算有多少个定时器
    var k = 0
    // 动画 - 定时器
    // 定时器的数量取决于obj中键值对数量
    // 通过for in 遍历obj,在循环中创建定时器
    for(var key in obj){
        k++ // 统计定时器数量
        // 在循环中嵌套了异步代码,异步代码中就无法准确的获取到每次遍历的变量了
        // 在定时器中的key是循环结束以后的key - 使用自调用函数解决
        (function(key){
            var timerId = setInterval(function(){
                // 获取left
                // console.log(key);
                var currentStyle = getComputedStyle(ele)[key] // 带px
                var target = obj[key]
                // 如果属性是opacity - 将当前的透明度扩大100被来处理
                if(key === 'opacity'){
                    currentStyle *= 100
                    target *= 100
                }
                
                // 取整,将px去掉
                currentStyle = parseInt(currentStyle)
                // 因为有的距离远,有的距离近,所以以同样的速度动画,多个属性不均匀
                // 每次走 剩下的距离 / 10 - 瑕疵:走不都头 - 取整
                var speed = (target - currentStyle) / 20
                // 取整 - 正数就向上取整,负数就向下取整
                if(speed > 0){
                    speed = Math.ceil(speed)
                }else{
                    speed = Math.floor(speed)
                }
                // 把数字加大
                currentStyle += speed
                // 限制left的最大值 - 将>=换成===,因为最后移动的距离,1px  1px 挪过去的,所以一定不会跳过目标值
                
                // 将数字设置为box的left
                if(key === 'opacity'){
                    ele.style[key] = currentStyle / 100
                }else{
                    ele.style[key] = currentStyle + 'px'
                }
                if(currentStyle === target){
                    currentStyle = target
                    clearInterval(timerId)
                    // 每清除一次定时器,就让计数器--
                    k--
                    // 当k=0的时候,所有定时器就都结束了
                    if(k === 0){
                        // ele.style.backgroundColor = '#0f0'
                        // alert('动画结束')
                        // 希望这里的代码固定不变的,不要每次修改 - 每次都能满足调用的需求
                        fn()
                    }
                }
            }, 20)
        })(key)
    }
}

封装后代码:


<!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{
    width: 3000px;
    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 ol li.active{
    background-color: #f00;
}
.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>
        <li>
            <a href="">
                <img src="./images/1.jfif" alt="">
            </a>
        </li>
        <li>
            <a href="">
                <img src="./images/2.webp" alt="">
            </a>
        </li>
        <li>
            <a href="">
                <img src="./images/3.jfif" alt="">
            </a>
        </li>
    </ul>
    <ol>
        <li class="active"></li>
        <li></li>
        <li></li>
    </ol>
    <a href="javascript:;" class="leftBtn">&lt;</a>
    <a href="javascript:;" class="rightBtn">&gt;</a>
</div>
</body>
<script src="./js/utils.js"></script>
<script>
// 1.获取元素
// 2.给ul的前后各复制一个li
// 3.调整ul的left值
// 4.开始轮播图效果 - 都是在操作下标 - 从右箭头点击开始
var ul = document.querySelector('.carousel ul');
// 复制
var firstLi = ul.firstElementChild.cloneNode(true)
// console.log(firstLi);
var lastLi = ul.lastElementChild.cloneNode(true)
// 分别放在末尾和最前面
ul.appendChild(firstLi)
ul.insertBefore(lastLi, ul.firstElementChild)
// 调整left
ul.style.left = -firstLi.offsetWidth + 'px'

// 获取ol
var ol = document.querySelector('.carousel ol');
// 定义下标
var index = 1
// 定义开关
var flag = true
// 右箭头点击
var rightBtn = document.querySelector('.carousel>a.rightBtn');
rightBtn.onclick = function(){
    // 判断开关
    if(!flag) return false
    // 动画开始 - 开关关闭
    flag = false
    // 操作下标
    index++;
    move()
}

// 左箭头点击
var leftBtn = document.querySelector('.carousel>a.leftBtn');
leftBtn.onclick = function(){
    if(!flag) return false
    flag = false
    // 操作下标
    index--;
    // 让ul开始动画
    move()
}

// 小圆点点击
for(var j=0;j<ol.children.length;j++){
    (function(j){
        ol.children[j].onclick = function(){
            if(!flag) return false
            flag = false
            index = j+1
            move()
        }
    })(j)
}

// 自动轮播
var timerId
auto()

// 大盒子的移入移出
var carousel = document.querySelector('.carousel');
carousel.onmouseover = function(){
    clearInterval(timerId)
}

carousel.onmouseout = function(){
    auto()
}

// 封装轮播核心代码
function move(){
    animate(ul, {
        left: -index * firstLi.offsetWidth
    }, function(){
        // 限制index 的最大值
        if(index === 0){
            index = ul.children.length-2
            ul.style.left = -index * firstLi.offsetWidth + 'px'
            console.log(-index * firstLi.offsetWidth);
        }
        if(index === ul.children.length-1){
            index = 1
            ul.style.left = -index * firstLi.offsetWidth + 'px'
            console.log(-index * firstLi.offsetWidth);
        }
        // 动画结束后
        // 操作小圆点
        // 将所有小圆点的active去掉
        for(var i=0;i<ol.children.length;i++){
            ol.children[i].className = ''
        }
        // 给当前对应的小圆点添加active
        ol.children[index-1].className = 'active'
        flag = true
    })
}

// 封装自动轮播
function auto(){
    timerId = setInterval(function(){
        rightBtn.onclick()
    }, 500)
}
</script>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值