js实现网站首页轮播图

一、案例

小米官网

二、功能需求

1、结构:轮播图片+底部导航条/小圆点+左右切换按钮

2、图片自动轮播,底部导航条/小圆点跟着切换

3、点击切换按钮,切换图片

4、点击底部导航条/小圆点,切换图片


三、html结构

1、结构简图

2、html代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>轮播图</title>

<body>
    <!-- 轮播区间 -->
    <div class="swiper-container">

        <!-- 轮播图片 -->
        <ul class="swiperLists">
            <li class="swiper-li"><a href="#"><img src="../static/images/swiperImage/swiper1.jpg"></a></li>
            <li class="swiper-li"><a href="#"><img src="../static/images/swiperImage/swiper2.jpg"></li>
            <li class="swiper-li"><a href="#"><img src="../static/images/swiperImage/swiper3.jpg"></li>
        </ul>

        <!-- 左按钮 -->
        <a href="#" class="left">&lt;</a>
        <!-- 右按钮 -->
        <a href="#" class="right">&gt;</a>

        <!-- 导航条:有序列表 -->
        <ol class="swiper-nav">
            <li class="current"></li>
            <li class="others"></li>
            <li class="others></li>
        </ol>

    </div>

</body>
</html>

四、css样式设置外观和布局

1、将所有元素margin,padding重置为0

* {
    padding: 0;
    margin: 0;
}

2、去除列表样式

ul,
ol {
    list-style: none;
}

3、轮播区域样式:宽高、相对定位(作为父级)、超出部分隐藏

/* 轮播区域样式 */
.swiper-container {
    width: 1422px;
    height: 600px;
    position: relative;
    overflow: hidden;
}

4、轮播图片的样式:

给图片集设置宽度1000%,使其能容纳所有图片。

给图片设置浮动,使其水平排列

/* 轮播图片样式 */
.swiper-container .swiperLists {
    width: 1000%;
}

.swiper-container .swiper-li {
    float: left;

}

5、左右按钮样式

给他们添加绝对定位,将他们定位到轮播区域的固定位置。

并添加hover,鼠标悬停时更改颜色。

.left,
.right {
    position: absolute;
    top: 280px;
    color: #fff;
    text-decoration: none;
    font-weight: 700;
    font-size: 26px
}

.left {
    left: 50px;
}

.right {
    right: 50px;
}

.left:hover {
    /* 鼠标悬停在左右按钮时变色 */
    color: #FF6900;
}

.right:hover {
    color: #FF6900;
}

6、顶部导航条样式

导航条的容器设置绝对定位

容器内每个导航条设置浮动,使其水平排列

.swiper-nav { /* 导航条容器 */
    position: absolute;
    left: 600px;
    bottom: 20px;
}
.swiper-nav li { /* 单个导航条 */
    float: left;
    width: 100px;
    height: 3px;
    background-color: #C9C8C7;
}
.swiper-nav .others:hover { /* 悬停变色 */
    background-color: #7E7E7E;
}
.swiper-nav .current { /* 当前导航条为橙色 */
    background-color: #FF6900;
}

7、引入css

<link rel="stylesheet" type="text/css" href="../css/轮播图.css" />

8、效果

五、js实现动态效果

功能一:鼠标移到轮播区域时,显示左右切换按钮,鼠标离开时隐藏

1、添加监听事件:load事件(页面加载完毕时执行),mouseenter事件(鼠标进入时执行),mouseleave事件(鼠标离开时执行)

window.addEventListener("load", function () {

    //1.获取元素
    var swiperContainer = this.document.querySelector(".swiper-container");
    var left = this.document.querySelector(".left");
    var right = this.document.querySelector(".right");

    //2.鼠标进入轮播区域:显示按钮
    swiperContainer.addEventListener("mouseenter", function () {
        left.style.display = "block"
        right.style.display = "block"
    })

    //3.鼠标离开轮播区域,隐藏按钮
    swiperContainer.addEventListener("mouseleave", function () {
        left.style.display = "none"
        right.style.display = "none"
    })

2、在html中引用js代码

<script src="../js/轮播图.js"></script>

3、效果

功能二:点击按钮切换图片

1、给swiperLists加定位,便于后续添加动画

2、新建animate.js文件,写动画函数。

  • offsetLeft获取元素左边界偏移量,判断元素是否到达目标点
  • 若没到达目标点,修改元素left属性使其移动,每次移动一个步长,添加计时器使其一直移动直到到达目标点
function animate(obj, target) { //参数:运动的对象,目标点

    clearInterval(obj.timer); //清除当前对象身上的计时器
    obj.timer = setInterval(function () { //添加新计时器

        var step = (target - obj.offsetLeft) / 10; //动态步长,先快后慢

        // 确保步长是整数
        //如果step大于0,math.ceil向上取整,即0.5取1
        //如果step小于0,math.floor向下取整,即-0.5取-1
        step = step > 0 ? Math.ceil(step) : Math.floor(step);

        if (obj.offsetLeft == target) { //offsetLeft:元素左边界偏移量
            clearInterval(obj.timer); //到达目标点停止运动,即清除计时器
        }

        //加法运算结果取整数,如果步长有小数的话会有误差
        obj.style.left = (obj.offsetLeft + step) + "px"; //运动到目标位置

    }, 10)
}
  • 遗留问题(求指教):怎样实现匀速移动?比如图片宽度1422,步长1422/10=144.2,每次移动144.2px,计时器循环10次移动到目标位置。obj.style.left = (obj.offsetLeft + step) + "px";这个运算会自动将step的小数位抹去,无法实现移动小数位步长
function animate(obj, target) { //参数:运动的对象,目标点
    clearInterval(obj.timer); //清除当前对象身上的计时器
    var step = (target - obj.offsetLeft) / 10; //固定步长
    console.log("step=" + step);
    obj.timer = setInterval(function () { //添加新计时器
        
        if (obj.offsetLeft == target) { //offsetLeft:元素左边界偏移量
            clearInterval(obj.timer); //停止运动,即清除计时器
        }

        obj.style.left = (obj.offsetLeft + step) + "px"; //运动到目标位置
        console.log("offsetLeft=" + obj.offsetLeft);
    }, 10)
}

3、在html中引入animate.js(要写在轮播图.js前面,因为轮播图.js中使用了动画函数)

<!-- 引入js -->
<script src="../js/animate.js"></script>
<script src="../js/轮播图.js"></script>

4、在轮播图.js中给right按钮添加点击事件。offsetWidth获取图片宽度,再乘以索引值就是移动距离。

//1.获取元素
var swiperLists = this.document.querySelector(".swiperLists");
var imgWidth = swiperContainer.offsetWidth; //图片宽度
//2.right按钮的点击事件
right.addEventListener("click", function () {
      index++; //点击下一张,图片索引值加一
      animate(swiperLists, -(index * imgWidth));
})

5、难点:最后一张切换到第一张

  • 将第一张图片复制一份到列表末尾
  • 每次点击下一张按钮时,先判断当前图片是否为克隆图片(若为克隆图片,将当前图片切换为第一张图片)
  • 调用animate函数移动到下一张图片
    //right按钮的点击事件
    var firstImg = swiperLists.children[0].cloneNode(true); //克隆swiperLists第一个孩子,即第一张图片
    swiperLists.appendChild(firstImg); //将克隆图片添加到swiperLists末尾

    right.addEventListener("click", function () { //点击下一张按钮
        if (index == swiperLists.children.length - 1) { //先判断当前是否为克隆图片
            swiperLists.style.left = 0; //若为克隆图片,将图片切换到第一张
            index = 0;
        }
        index++; //图片索引值加一
        animate(swiperLists, -(imgWidth * index)); //移动到下一张
    })

6、left按钮同理

  • 先判断是否为第一张图片
  • 若为第一张图片,将当前图片切换为克隆图片
  • 再调用animate函数移动到上一张(第一张→克隆图片→最后一张,由于克隆图片和第一张图片一样,所以视觉效果为:第一张→最后一张)
    //left按钮的点击事件
    left.addEventListener("click", function () { //点击上一张按钮
        if (index == 0) { //先判断当前是否是第一张图片
            index = swiperLists.children.length - 1; //3
            swiperLists.style.left = -index * imgWidth + "px"; //若为第一张图片,将图片切换到克隆图片
        }
        index--; //图片索引值减一    2
        animate(swiperLists, -index * imgWidth); //移动到上一张(克隆图片的上一张为:最后一张图片)
    })
功能三:根据图片数量自动生成导航条

1、删除<ol>标签下的<li>,便于后续生成

        <!-- 导航条:有序列表 -->
        <ol class="swiper-nav">

        </ol>

2、动态生成导航条

//1、根据类名获取<ol>标签
var swiperNav = this.document.querySelector(".swiper-nav");

//2、创建<li>标签,插入<ol>中
for (i = 0; i < swiperLists.children.length; i++) {
    var li = document.createElement("li"); //创建li标签
    li.className = "others"; //给li标签添加class属性
    swiperNav.appendChild(li); //将li标签插入到swiperNav中
}

3、效果

功能四:点击按钮切换图片,导航条随图片改变

1、index为图片索引值,所以根据index值切换导航条。注意克隆图片的原型为第一张图片,当显示克隆图片时切换到第一个导航条。创建changeNav()函数实现切换导航条功能。

    //图片与导航条对应
    function changeNav() {
        for (j = 0; j < swiperNav.children.length; j++) { //移除所有导航条的class属性
            swiperNav.children[j].className = "others";
        }
        if (index == swiperLists.children.length - 1) { //如果是克隆图片
            swiperNav.children[0].className = "current"; //因为克隆的是第一张图,所以第一个导航条被选中
            console.log("克隆图片");
        }
        else {
            console.log("普通图片");
            console.log(index);
            swiperNav.children[index].className = "current"; //当前导航条设置为选中状态

        }

    }

2、动态生成导航条后调用changeNav()方法,使第一个导航条默认选中

changeNav();

3、在之前写的right和left按钮的点击事件中调用changeNav()方法,使导航条随按钮点击而切换。

4、效果

功能五:点击导航条切换图片

1、给导航条添加点击事件,当导航条被点击时,根据其num值切换对应图片

        li.addEventListener("click", function () { //导航条点击事件
            for (j = 0; j < swiperNav.children.length; j++) { //移除所有导航条的class属性
                swiperNav.children[j].className = "others";
                console.log("remove");
            }
            this.className = "current"; //被点击的导航条选中
            var n = this.getAttribute("num"); //获取被点击导航条的num值
            animate(swiperLists, -(n * imgWidth)); //根据num值切换图片
        })

2、效果

功能六:自动轮播

1、添加计时器,每隔一段时间执行right按钮的点击事件

    //自动轮播
    var timer = this.setInterval(function () {
        right.click();
    }, 5000)

六、完整代码

1、项目结构

2、html代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>轮播图</title>

    <!-- 引入css -->
    <link rel="stylesheet" type="text/css" href="../css/轮播图.css" />

    <!-- 引入js -->
    <script src="../js/animate.js"></script>
    <script src="../js/轮播图.js"></script>
</head>

<body>
    <!-- 轮播区间 -->
    <div class="swiper-container">

        <!-- 轮播图片 -->
        <ul class="swiperLists">
            <li class="swiper-li">
                <a href="#"><img src="../static/images/swiperImage/swiper1.jpg"></a>
            </li>
            <li class="swiper-li">
                <a href="#"><img src="../static/images/swiperImage/swiper2.jpg"></a>
            </li>
            <li class="swiper-li">
                <a href="#"><img src="../static/images/swiperImage/swiper3.jpg"></a>
            </li>
        </ul>

        <!-- 左按钮 -->
        <a href="#" class="left">&lt;</a>
        <!-- 右按钮 -->
        <a href="#" class="right">&gt;</a>

        <!-- 导航条:有序列表 -->
        <ol class="swiper-nav">

        </ol>

    </div>



</body>

</html>

3、css代码

* {
    padding: 0;
    margin: 0;
}


/* 轮播区域样式 */
.swiper-container {
    width: 1422px;
    height: 600px;
    position: relative;
    overflow: hidden;
}


/* 去除列表的样式 */
ul,
ol {
    list-style: none;
}


/* 轮播图片样式 */
.swiper-container .swiperLists {
    width: 1000%;
    position: absolute;
    left: 0;
}

.swiper-container .swiper-li {
    float: left;

}


/* 左右按钮样式 */
.left,
.right {
    position: absolute;
    top: 280px;
    color: #fff;
    text-decoration: none;
    font-weight: 700;
    font-size: 26px
}

.left {
    left: 50px;
}

.right {
    right: 50px;
}

.left:hover {
    /* 鼠标悬停在左右按钮时变色 */
    color: #FF6900;
}

.right:hover {
    color: #FF6900;
}


/* 导航条样式 */
.swiper-nav {
    /* 导航条容器 */
    position: absolute;
    left: 600px;
    bottom: 20px;
}

.swiper-nav li {
    /* 单个导航条 */
    float: left;
    width: 100px;
    height: 3px;
    background-color: #C9C8C7;
}

.swiper-nav .others:hover {
    /* 悬停变色 */
    background-color: #7E7E7E;
}

.swiper-nav .current {
    /* 当前导航条为橙色 */
    background-color: #FF6900;
}

4、animate.js代码

function animate(obj, target) { //参数:运动的对象,目标点
    clearInterval(obj.timer); //清除当前对象身上的计时器
    obj.timer = setInterval(function () { //添加新计时器

        var step = (target - obj.offsetLeft) / 10; //动态步长,先快后慢
        // 确保步长是整数
        //如果step大于0,math.ceil向上取整,即0.5取1
        //如果step小于0,math.floor向下取整,即-0.5取-1
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        if (obj.offsetLeft == target) { //offsetLeft:元素左边界偏移量
            clearInterval(obj.timer); //停止运动,即清除计时器
        }
        //加法运算结果取整数,如果步长有小数的话会有误差
        obj.style.left = (obj.offsetLeft + step) + "px"; //运动到目标位置
    }, 10)
}

 5、轮播图.js代码

window.addEventListener("load", function () {

    // 定义全局变量
    var index = 0; //图片索引值

    //1.获取元素
    var swiperContainer = this.document.querySelector(".swiper-container");
    var left = this.document.querySelector(".left");
    var right = this.document.querySelector(".right");
    var swiperLists = this.document.querySelector(".swiperLists");
    var swiperNav = this.document.querySelector(".swiper-nav");
    var imgWidth = swiperContainer.offsetWidth; //图片宽度

    //动态生成导航条
    for (i = 0; i < swiperLists.children.length; i++) {
        var li = document.createElement("li"); //创建li标签
        li.className = "others"; //给li标签添加class属性
        li.setAttribute("num", i); //给li标签添加索引值
        swiperNav.appendChild(li); //将li标签插入到swiperNav中
        console.log("create");

        li.addEventListener("click", function () { //导航条点击事件
            for (j = 0; j < swiperNav.children.length; j++) { //移除所有导航条的class属性
                swiperNav.children[j].className = "others";
                console.log("remove");
            }
            this.className = "current"; //被点击的导航条选中
            var n = this.getAttribute("num"); //获取被点击导航条的num值
            animate(swiperLists, -(n * imgWidth)); //根据num值切换图片
        })

    }

    //图片与导航条对应
    function changeNav() {
        for (j = 0; j < swiperNav.children.length; j++) { //移除所有导航条的class属性
            swiperNav.children[j].className = "others";
        }
        if (index == swiperLists.children.length - 1) { //如果是克隆图片
            swiperNav.children[0].className = "current"; //因为克隆的是第一张图,所以第一个导航条被选中
            console.log("克隆图片");
        }
        else {
            console.log("普通图片");
            console.log(index);
            swiperNav.children[index].className = "current"; //当前导航条设置为选中状态

        }

    }
    changeNav();


    //2.鼠标进入轮播区域:显示按钮
    swiperContainer.addEventListener("mouseenter", function () {
        left.style.display = "block"
        right.style.display = "block"
    })

    //3.鼠标离开轮播区域,隐藏按钮
    swiperContainer.addEventListener("mouseleave", function () {
        left.style.display = "none"
        right.style.display = "none"
    })

    //4.right按钮的点击事件
    var firstImg = swiperLists.children[0].cloneNode(true); //克隆swiperLists第一个孩子,即第一张图片
    swiperLists.appendChild(firstImg); //将克隆图片添加到swiperLists末尾

    right.addEventListener("click", function () { //点击下一张按钮
        if (index == swiperLists.children.length - 1) { //先判断当前是否为克隆图片
            swiperLists.style.left = 0; //若为克隆图片,将图片切换到第一张
            index = 0;
        }
        index++; //图片索引值加一
        animate(swiperLists, -(imgWidth * index)); //移动到下一张
        changeNav();

    })

    //5.left按钮的点击事件
    left.addEventListener("click", function () { //点击上一张按钮
        if (index == 0) { //先判断当前是否是第一张图片
            index = swiperLists.children.length - 1; //3
            swiperLists.style.left = -index * imgWidth + "px"; //若为第一张图片,将图片切换到克隆图片
        }
        index--; //图片索引值减一    2
        animate(swiperLists, -index * imgWidth); //移动到上一张(克隆图片的上一张为:最后一张图片)
        changeNav();
    })

    //自动轮播
    var timer = this.setInterval(function () {
        right.click();
    }, 5000)

})

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值