2021-05-04 淘宝轮拨图的实现思路和完整代码

本文详细介绍了实现淘宝风格轮播图的需求和完整代码,包括鼠标交互时左右键的显示隐藏,点击按钮及序号切换图片,以及无点击时的自动播放功能。通过CSS和JavaScript技术,结合DOM操作,成功创建了这一交互式轮播组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章目录

需求

1.实现鼠标移入移出时左右键的显示和隐藏
2.点击左键实现切换到上一张,点击右键切换下一张
3.点击序号12345的小图标可以切换到对应的第几张图片,并且当前图片对应的序号被选中(变颜色)
4.没有鼠标点击时可以实现自动播放

代码
body
<div class="all" id="box">
    <div id="screen" class="screen">
        <ul>
            <li><img src="./pic/a.png" alt=""></li>
            <li><img src="./pic/b.png" alt=""></li>
            <li><img src="./pic/c.png" alt=""></li>
            <li><img src="./pic/d.png" alt=""></li>
            <li><img src="./pic/e.png" alt=""></li>
        </ul>
        <ol></ol>
    </div>
    <div id="arr">
        <span id="left">&lt;</span>
        <span id="right">&gt;</span>
    </div>
</div>
css
        * {
            padding: 0;
            margin: 0;
            list-style: none;
            border: 0;
        }
        
        .all {
            width: 500px;
            height: 300px;
            padding: 7px;
            border: 1px solid #ccc;
            margin: 100px auto;
            position: relative;
        }
        
        .screen {
            width: 500px;
            height: 300px;
            overflow: hidden;
            position: relative;
        }
        
        .screen li {
            width: 500px;
            height: 300px;
            overflow: hidden;
            float: left;
        }
        
        .screen ul {
            position: absolute;
            left: 0px;
            top: 0px;
            width: 3000px;
        }
        
        .all ol {
            position: absolute;
            right: 10px;
            bottom: 10px;
            line-height: 20px;
            text-align: center;
        }
        
        .all ol li {
            float: left;
            width: 20px;
            height: 20px;
            background: #fff;
            border: 1px solid #ccc;
            margin-left: 10px;
            cursor: pointer;
        }
        
        .all ol li.current {
            background: yellow;
        }
        
        #arr {
            display: none;
            z-index: 1000;
        }
        
        #arr span {
            width: 40px;
            height: 40px;
            position: absolute;
            left: 5px;
            top: 50%;
            margin-top: -20px;
            background: #000;
            cursor: pointer;
            line-height: 40px;
            text-align: center;
            font-weight: bold;
            font-family: '黑体';
            font-size: 30px;
            color: #fff;
            opacity: 0.3;
            border: 1px solid #fff;
        }
        
        #arr #right {
            right: 5px;
            left: auto;
        }
js
// 1.获取节点和设置全局变量
//获取节点
var box = document.querySelector('#box');
var screen = document.querySelector('#screen');
var ul = document.querySelector('ul');
var lis = ul.children;
var arr = document.querySelector('#arr');
var left = document.querySelector('#left');
var right = document.querySelector('#right');
var ol = document.querySelector('ol');
//设置全局变量
var isClick = true; //是否点击
var scWid = screen.offsetWidth; //图片总宽度
var imgIndex = -1; //保存图片索引
// 2.创建ol下的li标签,克隆第一张图片
//创建ol下的li标签
for (var i = 0; i < lis.length; i++) {
    var newLi = document.createElement("li");//创建5个li节点
    if (i == 0) newLi.classList.add('current')//默认选中第一张,也可以写成:i==0&&newLi.classList.add('current')
    newLi.setAttribute("index", i);//自定义属性index保存索引
    newLi.innerHTML = i + 1;//第几个li的序号就是几
    newLi.onclick = banner;//li被点击时调用banner函数
    ol.appendChild(newLi);//追加到ol下

}
//克隆第一张图片
var newImg = lis[0].cloneNode(true);//克隆节点,true是表示克隆lis[0]以及其所有子节点
newImg.style.borderTop = "red solid 1px";//以示不同,后面可以注释掉
ul.appendChild(newImg);//节点追加
// 3.点击ol>li切换图片
function banner() {
    imgIndex = this.getAttribute("index");//获取调用者的自定义属性index赋给imgIndex
    move(ul, {
        left: -(imgIndex * scWid)//实际上就是i*scWid,也就是第几张就把ul的left挪到对应的地方
    }, function() {
        isClick = true;
    })
    selectOl();//调用,否则跳转到第i张,对应的ol>li小图标不会相应地被选中(变黄)
}
// 4.获取图片对应的索引值
//这个函数的作用是取消之前选中,并让当前图片对应的索引被选中
function selectOl() {
    for (var i = 0; i < ol.children.length; i++) {
        ol.children[i].classList.remove("current");
    }
    ol.children[imgIndex].classList.add("current");
}
// 5.鼠标移入移出,左右键显示与隐藏
box.onmouseover = () => {
    arr.style.display = 'block';
}
screen.onmouseout = () => {
        arr.style.display = 'none';
    }
// 6.点击上一张
    /*点击上一张做了什么?
    先判断是否点击 如果没有点击(即!isClick=true),那就返回,不要继续往下了
    判断:是否当前移到第一张
        是:把所有图片显示在左侧(才能继续点击 上一张)
            做法:把imgIndex(保存索引的变量)改为第五张的索引(4),
            并显示克隆的第六张(让ul的left为-5*scWid)
        否:序号自减
    调用序号点击的方法:newLi的onclick()
        目的是让current选中(黄色显示的)也跟着改变,点击上一张也等价于点击了一次newLi
    */
left.onclick = function() {
    if (!isClick) return;
    isClick = false;
    if (imgIndex == 0) { //第一张:把图片显示在左侧
        ul.style.left = -(ul.children.length - 1) * scWid; //5*500
        imgIndex = ul.children.length - 1 - 1; //4(下标变成第五张的下标)
    } else { //不是第一张:索引自减
        imgIndex--;
    }
    ol.children[imgIndex].onclick();
};
// 7.点击下一张
/*点击下一张做了什么?
先判断是否点击 如果没有点击(即!isClick=true),那就返回不要继续往下了
判断:是否移到了第五张(imgIndex==4)
    是:运动到克隆的第六张,到达时(回调)让ul的left为0回到第一张
        做法:调用运动函数的封装,让运动主体ul的left为-5*scWid,(5写成imgIndex+1)
        在回调中让ul的left为0,isClick变为true
    否:索引自增,并调用序号点击的方法
    注:调用序号点击方法的时机只要不在第一张/最后一张的if{}中就行
*/
right.onclick = function() {
    if (!isClick) return;
    isClick = false;
    if (imgIndex == ul.children.length - 1 - 1) {
        move(ul, {
            left: -(imgIndex - 0 + 1) * scWid
        }, function() {
            isClick = true;
            ul.style.left = "0px";
        });
        selectOl();
        imgIndex = 0;
    } else {
        imgIndex++;
        ol.chlidren[imgIndex].onclick();
    }
};
// 8.自动播放
/*如何实现自动播放?
在定时器中不断调用right的点击事件即可*/
function autoPlay() {
    var times = null;
    clearInterval(times);
    times = setInterval(() => {
        right.onclick();
    }, 3000);
}
autoPlay();


/*****运动函数封装*****/
function move(eleObj, objArr, cb) {
    //使用前先清除定时器
    var timer = null;
    clearInterval(timer);
    //  设置开关用于判断是否要清除定时器
    var onOff = false;
    timer = setInterval(() => {
        // 遍历元素属性
        for (var attr in objArr) {
            //获取元素的实时属性值
            var tmpPos = parseInt(getPos(eleObj, attr));
            // 设置步长
            var speed = (objArr[attr] - tmpPos) / 10;
            speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
            // 开始运动
            if (tmpPos + speed == objArr[attr]) {
                onOff = true;
            } else {
                eleObj.style[attr] = speed + tmpPos + "px";
            }
        }
    }, 30);
}
//获取元素的实时属性值的封装
function getPos(obj, attr) {
    if (obj.currentStyle) return obj.currentStyle[attr];
    else return getComputedStyle(obj)[attr];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端OnTheRun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值