无缝轮播图(自动轮播+点击轮播+拖拽轮播)

废话不多说,直接上代码(注:js部分代码会有截图对其解释)

一、HTML

html 复制代码
    <div class="bigBox">
        <!-- 轮播主体 -->
        <div class="box">
            <div class="littleBox">1</div>
            <div class="littleBox">2</div>
            <div class="littleBox">3</div>
        </div>
        <!-- 底部小点 -->
        <div class="point">
            <div class="active"></div>
            <div></div>
            <div></div>
        </div>
        <!-- 上一页 -->
        <div class="prev"></div>
        <!-- 下一页 -->
        <div class="next"></div>
    </div>

二、CSS

css 复制代码
* {
    margin: 0;
    padding: 0;
}

.bigBox {
    width: 300px;
    height: 180px;
    border: 2px solid black;
    overflow: hidden;
    margin: 100px auto;
    position: relative;
}

/* 轮播主体 */
.box {
    width: 900px;
    display: flex;
    transition: all .6s;
}

.littleBox {
    text-align: center;
    line-height: 180px;
    width: 300px;
    height: 180px;
}

.littleBox:nth-of-type(1) {
    background-color: skyblue;
}

.littleBox:nth-of-type(2) {
    background-color: pink;
}

.littleBox:nth-of-type(3) {
    background-color: yellow;
}

/* 小点 */
.point {
    position: absolute;
    width: 50px;
    height: 10px;
    bottom: 10px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    justify-content: space-evenly;
    cursor: pointer;
}

.point div {
    width: 10px;
    height: 10px;
    background-color: rgb(151, 151, 151);
    border-radius: 10px;
}

.point .active {
    background-color: white;
}

/* 上一页/下一页 */
.prev::after,
.next::after {
    position: absolute;
    width: 20px;
    height: 30px;
    top: 50%;
    transform: translateY(-50%);
    background-color: aliceblue;
    line-height: 30px;
    text-align: center;
    cursor: pointer;
}

/* 上一页 */
.prev::after {
    content: '<';
    left: 0;
    border-top-right-radius: 15px;
    border-bottom-right-radius: 15px;
}

/* 下一页 */
.next::after {
    content: '>';
    right: 0;
    border-top-left-radius: 15px;
    border-bottom-left-radius: 15px;
}

三、JS以及解释截图

javascript 复制代码
// dom元素
const doms = {
    box: document.querySelector('.box'),
    point: document.querySelectorAll('.point div'),
    prev: document.querySelector('.prev'),
    next: document.querySelector('.next')
}

// 当前所在页面(从0开始)
let currentIndex = 0

// 切换页面
function moved(index) {
    currentIndex = index
    const x = -300 * index
    doms.point.forEach((item, i) => {
        item.classList.remove('active')
    })
    doms.point[index].classList.add('active')
    doms.box.style.transform = `translateX(${x}px)`
}

// 上一页点击事件
function changePrev() {
    currentIndex === 0 ? currentIndex = 2 : currentIndex--
    moved(currentIndex)
}
doms.prev.addEventListener('click', changePrev)

// 下一页点击事件
function changeNext() {
    currentIndex === 2 ? currentIndex = 0 : currentIndex++
    moved(currentIndex)
}
doms.next.addEventListener('click', changeNext)

// 小点点击事件
doms.point.forEach((item, i) => {
    item.addEventListener('click', function () {
        moved(i)
    })
})

// 自动轮播
let timer = setInterval(changeNext, 2000)

// 鼠标移入后清除自动轮播
doms.box.addEventListener('mouseenter', function () {
    clearInterval(timer)
})

// box元素相对视口的位置
const boxPosition = {
    x: Math.floor(doms.box.getBoundingClientRect().x),
    y: Math.floor(doms.box.getBoundingClientRect().y)
}

// 鼠标最初位置
let mouseX = 0

// box移动的位置
let transformX = 0
let x = 0

// 手动拖拽
function onMoueseDown(e) {
    mouseX = e.clientX - boxPosition.x
    doms.box.addEventListener('mousemove', onMoueseMove)
}

function onMoueseMove(e) {
    e.preventDefault()
    x = transformX + -1 * (mouseX - (e.clientX - boxPosition.x));
    doms.box.style.transform = `translateX(${x}px)`
}

function onMoueseUp() {
    // 判断当前页数
    if (Math.round(-1 * x / 300) < 0) {
        currentIndex = 2
    } else if (Math.round(-1 * x / 300) > 2) {
        currentIndex = 0
    } else {
        currentIndex = Math.round(-1 * x / 300)
    }
    transformX = currentIndex * -300
    moved(currentIndex)
    // 移出监听
    doms.box.removeEventListener('mousemove', onMoueseMove)
}


function onMoueseLeave() {
    // 移出监听
    doms.box.removeEventListener('mousemove', onMoueseMove)
    // 添加自动轮播
    timer = setInterval(changeNext, 2000)
}
// 鼠标按下添加拖拽
doms.box.addEventListener('mousedown', onMoueseDown)

// 鼠标抬起移除事件
doms.box.addEventListener('mouseup', onMoueseUp)
// 鼠标移出后添加自动轮播以及移出事件
doms.box.addEventListener('mouseleave', onMoueseLeave)

解释截图(最左侧为可视窗口最左侧):

相关推荐
有味道的男人14 分钟前
搜好货平台关键词商品搜索接口:分页容错与商品数据轻量化提取方案
服务器·前端·javascript
lovingsoft1 小时前
Chrome Lighthouse 详解
前端·chrome
Qlly1 小时前
全栈工程师怎么接需求?从一句「加个功能」聊到能开发、能验收
前端·后端
马可家的菠萝1 小时前
你的微信“文件传输助手”,是不是已经成了第二个网盘?
前端·后端·架构
略略略啦1 小时前
Vibe Coding 基于Spec DD和TDD的实践指南
前端
shmily麻瓜小菜鸡1 小时前
前端实现图片与PDF文字识别敏感信息打码方案
前端·pdf·状态模式
打工仔折腾 AI2 小时前
LangChain 工具调用实战:从 Tool 定义到 Agent 执行链路拆解
java·前端·人工智能·后端·python·langchain·ai agent 实战
汉堡大王95272 小时前
单次输出拉到100万Token:拆完 Gemini 4 Argon 的续写协议,才看懂谷歌这7个月在憋什么
前端·人工智能·后端
看浪的路人2 小时前
第9讲:大模型应用监控与可观测性——OpenTelemetry + Prometheus + Grafana 全链路追踪
java·前端·spring
内存过载2 小时前
用表格模拟甘特图:项目排期的土办法
前端·低代码