如何实现带有鼠标滚轮支持的轮播图

轮播图是一种常见的网页元素,用于展示一组图片或内容。为了让用户体验更加流畅和互动,我们可以为轮播图添加鼠标滚轮支持,并在用户尝试滚动到第一张或最后一张时显示提示信息。本文将详细介绍如何使用 jQuery 实现这一功能。

项目结构

首先,确保你的 HTML 文件包含以下基本结构:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Carousel</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="carousel-focus">
        <ul class="carousel-focus-slide">
            <li><img src="image1.jpg" alt="Image 1"></li>
            <li><img src="image2.jpg" alt="Image 2"></li>
            <li><img src="image3.jpg" alt="Image 3"></li>
            <!-- 添加更多图片 -->
        </ul>
        <ul class="carousel-focus-nav"></ul>
        <div class="carousel-focus-icon-left">&lt;</div>
        <div class="carousel-focus-icon-right">&gt;</div>
    </div>

    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="scripts.js"></script>
</body>
</html>

CSS 样式

接下来,我们需要定义一些基本的 CSS 样式来美化轮播图:

.carousel-focus {
    position: relative;
    overflow: hidden;
}
 
.carousel-focus li {
    list-style: none;
}
 
#carousel-focus-slide {
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    margin: 0;
    display: flex;
    flex-direction: row;
    white-space: nowrap;
}
 
#carousel-focus-slide li {
    float: left;
    height: 100%;
    margin: 0;
}
 
#carousel-focus-slide li img {
    max-width: 100%;
    height: 100%;
    margin: 0 auto;
}
 
ol.carousel-focus-nav {
    position: absolute;
    padding: 0 15px;
    height: 20px;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    border-radius: 10px;
    background-color: rgba(0, 0, 0, .3);
    margin: 0;
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    white-space: nowrap;
}
 
.carousel-focus-icon-left {
    display: none;
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    width: 40px;
    height: 40px;
    background-color: rgba(0, 0, 0, .3);
    cursor: pointer;
}
 
.carousel-focus-icon-left::after {
    content: '';
    position: absolute;
    top: 10px;
    left: 15px;
    width: 20px;
    height: 20px;
    transform: rotate(-135deg);
    border-top: 1px solid #fff;
    border-right: 1px solid #fff;
}
 
.carousel-focus-icon-right {
    display: none;
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    width: 40px;
    height: 40px;
    background-color: rgba(0, 0, 0, .3);
    cursor: pointer;
}
 
.carousel-focus-icon-right::after {
    content: '';
    position: absolute;
    top: 10px;
    right: 15px;
    width: 20px;
    height: 20px;
    transform: rotate(45deg);
    border-top: 1px solid #fff;
    border-right: 1px solid #fff;
}
 
ol.carousel-focus-nav li {
    float: left;
    width: 14px;
    height: 14px;
    border-radius: 7px;
    margin: 3px 7px;
    background-color: #fff;
    cursor: pointer;
}
 
ol.carousel-focus-nav li.carousel-focus-nav-current {
    background-color: orange;
}

.carousel-focus-notification {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translateX(-50%) translateY(-50%);
    background-color: rgba(0, 0, 0, 0.7);
    color: white;
    padding: 10px 20px;
    border-radius: 5px;
    z-index: 9999;
    display: none;
}

JavaScript 功能实现

最后,我们编写 JavaScript 代码来实现轮播图的功能,包括自动播放、点击按钮切换、鼠标滚轮滚动以及边界提示信息。

$(function() {
    let slideWidth = 0; // 初始化slideWidth为0
    
    // 定义节流阀,防止图片切换过快
    let flag = true;

    // 设置定时器,自动播放图片
    let timer = setInterval(function() {
        $(".carousel-focus-icon-right").click(); // 每3秒点击右侧按钮以切换到下一张图片
    }, 3000);

    let num = $("#carousel-focus-slide").children().length; // 获取轮播图中图片的数量
    let number = 0; // 当前显示的图片索引
    let startX, startY, endX, endY; // 触摸事件的起始和结束坐标

    function updateSlideWidth() {
        slideWidth = $('.carousel-focus').width(); // 更新slideWidth为当前容器的宽度
        $("#carousel-focus-slide li").css("width", slideWidth + "px"); // 设置每张图片的宽度与容器一致
    }

    // 封装成函数,减少代码量
    function getslide() {
        $("#carousel-focus-slide").animate({
            left: -number * slideWidth // 动画切换到指定索引的图片
        }, 500, function() {
            flag = true; // 动画完成后再将flag设为true
        });
        // 更新指示器
        $(".carousel-focus-nav li").removeClass('carousel-focus-nav-current').eq(number).addClass('carousel-focus-nav-current'); // 更新导航指示器高亮状态
    };

    updateSlideWidth(); // 初始化时更新slideWidth

    // 监听窗口大小变化并更新 slideWidth
    $(window).resize(updateSlideWidth); // 窗口大小改变时重新计算slideWidth
	
	// 动态创建小圆圈 数量根据ul li的数量决定
    for (let i = 0; i < num; i++) {
        $('.carousel-focus-nav').append('<li data-index="' + i + '"></li>'); // 根据图片数量动态创建导航小圆点
    }
    // 给ol 里面面的第一个li添加carousel-focus-nav-current类名
    $(".carousel-focus-nav li").eq(0).addClass('carousel-focus-nav-current'); // 默认第一个小圆点高亮

    // 当鼠标移入carousel-focus时,显示左右按钮并停止自动滚动
    $('.carousel-focus').on('mouseenter', function() {
        $('.carousel-focus-icon-left').css('display', 'block'); // 显示左侧按钮
        $('.carousel-focus-icon-right').css('display', 'block'); // 显示右侧按钮
        clearInterval(timer); // 鼠标悬停时停止自动播放
        timer = null;
    });

	// 当鼠标移除carousel-focus时,隐藏左右按钮并恢复自动滚动
    $('.carousel-focus').on('mouseleave', function() {
        $('.carousel-focus-icon-left').css('display', 'none'); // 隐藏左侧按钮
        $('.carousel-focus-icon-right').css('display', 'none'); // 隐藏右侧按钮
        // 创建定时器,继续轮播
        timer = setInterval(function() {
            $(".carousel-focus-icon-right").click(); // 鼠标离开后恢复自动播放
        }, 3000);
    });
	
	// 点击小圆点实现ul的轮播效果
    $(".carousel-focus-nav li").on('click', function() {
        number = parseInt($(this).attr('data-index')); // 获取点击的小圆点对应的索引
        $('#carousel-focus-slide').animate({ left: -number * slideWidth }); // 切换到对应索引的图片
        $(".carousel-focus-nav li").removeClass('carousel-focus-nav-current').eq(number).addClass('carousel-focus-nav-current'); // 更新导航指示器高亮状态
    });

    // 点击右侧按钮实现ul的轮播效果
    $(".carousel-focus-icon-right").on('click', function() {
        if (!flag) return; // 如果正在动画则返回
        flag = false; // 设置节流阀为false,防止快速点击
        number++; // 图片索引加1
        if (number >= num) {
            number = 0; // 如果超过最后一张,则跳转到第一张
        }
        getslide(); // 调用getslide函数进行图片切换
    });

    // 点击左侧按钮实现ul的轮播效果
    $(".carousel-focus-icon-left").on('click', function() {
        if (!flag) return; // 如果正在动画则返回
        flag = false; // 设置节流阀为false,防止快速点击
        number--; // 图片索引减1
        if (number < 0) {
            number = num - 1; // 如果小于第一张,则跳转到最后一张
        }
        getslide(); // 调用getslide函数进行图片切换
    });

    // 鼠标滚轮滑动支持
    $('.carousel-focus').on('mousewheel DOMMouseScroll', function(event) {
        event.preventDefault(); // 阻止默认滚动行为
        if (!flag) return; // 如果正在动画则返回
        flag = false; // 设置节流阀为false,防止快速滚动
        if (event.originalEvent.wheelDelta > 0 || event.originalEvent.detail < 0) {
            // 向上滚动或向右滚动
            number--; // 图片索引减1
            if (number < 0) {
                number = num - 1; // 如果小于第一张,则跳转到最后一张
            }
        } else {
            // 向下滚动或向左滚动
            number++; // 图片索引加1
            if (number >= num) {
                number = 0; // 如果超过最后一张,则跳转到第一张
            }
        }
        getslide(); // 调用getslide函数进行图片切换
    });

    // 触摸开始事件
    $('.carousel-focus').on('touchstart', function(event) {
        startX = event.originalEvent.touches[0].clientX; // 记录触摸开始时的x坐标
        startY = event.originalEvent.touches[0].clientY; // 记录触摸开始时的y坐标
    });

    // 触摸结束事件
    $('.carousel-focus').on('touchend', function(event) {
        endX = event.originalEvent.changedTouches[0].clientX; // 记录触摸结束时的x坐标
        endY = event.originalEvent.changedTouches[0].clientY; // 记录触摸结束时的y坐标
        const deltaX = startX - endX; // 计算水平方向上的移动距离
        const deltaY = startY - endY; // 计算垂直方向上的移动距离
        // 判断水平滑动还是垂直滑动
        if (Math.abs(deltaX) > Math.abs(deltaY)) {
            if (!flag) return; // 如果正在动画则返回
            flag = false; // 设置节流阀为false,防止快速滑动
            if (deltaX > 0) {
                // 向左滑动
                number++; // 图片索引加1
                if (number >= num) {
                    number = 0; // 如果超过最后一张,则跳转到第一张
                }
            } else {
                // 向右滑动
                number--; // 图片索引减1
                if (number < 0) {
                    number = num - 1; // 如果小于第一张,则跳转到最后一张
                }
            }
            getslide(); // 调用getslide函数进行图片切换
        }
    });
});

通过以上步骤,我们成功实现了一个带有鼠标滚轮支持的轮播图,并且在用户尝试滚动到第一张或最后一张时显示了相应的提示信息。你可以根据实际需求进一步调整样式和逻辑,以满足不同的应用场景。

发表回复