js+html+css轮播图

功能预览

js+html+css轮播图

实现步骤
  1. 搭建静态框架
    1. 轮播图实现核心在于:设置图片盒子ul相对于父盒子div的left数值
    2. 基于以上原理,需要先将图片显示在一条线上,实现左浮动的效果
    3. 实现代码如下:
      html 代码
<div class="sildeshow">
<!--    左侧按钮-->
    <a href="javascript:;" class="arrow-l">⬅</a>
<!--    右侧按钮-->
    <a href="javascript:;" class="arrow-r">➡</a>
<!--    滚动区域-->
    <ul>
        <li>
            <a href="#"><img src="../imgs/OIP.jpg" alt="图片"></a>
        </li>
        <li>
            <a href="#"><img src="../imgs/green_bg.jpg" alt="图片"></a>
        </li>
        <li >
            <a href="#"><img src="../imgs/grils.png" alt="图片"></a>
        </li>
    </ul>
<!--    点击圆圈区域-->
    <ol class="circle"></ol>
</div>

css代码

ul,
ol {
    margin: 0;
    padding: 0;
    list-style-type: none;
}


.sildeshow {
    position: relative;
    margin: 0 auto;
    width: 760px;
    height: 400px;
    /*border: 1px solid #86c4d6;*/
    /*background-color: #999999;*/
    overflow: hidden;
}

.sildeshow ul {
    position: absolute;
    top: 0px;
    left: 0px;
    width: 400%;
    height: 100%;
}

.sildeshow ul li {
    float: left;
}

img {
    width: 760px;
    height: 400px;
}

a {
    text-decoration: none;
}

.arrow-l {
    display: none;
    position: absolute;
    top: 200px;
    left: 10px;
    font-size: 30px;
    color: #fff;
    z-index: 9;
}

.arrow-r {
    display: none;
    position: absolute;
    top: 200px;
    right: 10px;
    font-size: 30px;
    color: #fff;
    z-index: 9;
}
.circle {
    position: absolute;
    bottom: 10px;
    left: 50px;
    z-index: 9;
}

.circle li {
    float: left;
    width: 10px;
    height: 10px;
    /*background-color: #fff;*/
    border: 3px solid rgba(255, 255, 255, 0.5);
    margin: 0 3px;
    border-radius: 50%;
    /*鼠标经过显示小手*/
    cursor: pointer;
}

.current_circle {
    background-color: #fff;
}
  1. 鼠标经过以及离开注册事件
    1. 当鼠标经过的时候,设置注册事件,显示左右图标,并移除定时器(其中,定时器实现轮播图的自动播放效果)
    2. 当鼠标离开的时候,设置注册事件,隐藏左右图标,并设置定时器。
    3. 实现代码如下
     var sildeshow = document.querySelector('.sildeshow');
    var arrow_l = document.querySelector('.arrow-l');
    var arrow_r = document.querySelector('.arrow-r');
    
    // 鼠标经过轮播图 显示隐藏左右箭头
    sildeshow.addEventListener('mouseenter',function () {
        arrow_l.style.display = 'block';
        arrow_r.style.display = 'block';
        // 终止计时器
        clearInterval(timer);
        timer = null;
    })
    
    sildeshow.addEventListener('mouseleave',function () {
        arrow_l.style.display = 'none';
        arrow_r.style.display = 'none';
        timer = setInterval(function () {
        //  手动调用计时器
            arrow_r.click();
        },2000);
    })
    
  2. 底部小圆圈动态生成以及注册点击事件
    1. 首先根据图片的个数来动态生成li标签,从而实现动态显示小圆圈
    2. 给每个li标签添加点击注册事件,实现点击不同小圆圈切换不同图片,实现如下
      1. 给每个li标签添加自定义属性以便与每个图片建立索引上的联系
       li.setAttribute('data-index',i);
      
      1. 在li标签点击事件中,计算图片盒子ul偏移量。由于每个图片的宽度和父盒子ul都是一样的,所以可以建立索引与ul偏移量的方式显示每个盒子,也即ul偏移 = -1 * (图片索引 * ul父盒子宽度)。
      var li = document.createElement('li');
      //  点击小圆圈 切换图片
          var index = this.dataset.index;
            var sildeshowWidth = ul.querySelectorAll('img')[index].offsetWidth + 4;
          animate(ul,-index * sildeshowWidth,15);
      
      此处涉及的animate函数详见js动画函数实现侧边栏动态显示内容.
  3. 左右箭头注册点击事件
    1. 为左右箭头注册点击事件
    2. 当右箭头被点击(左箭头类似)时,会涉及到的业务逻辑为:图片切换同时小圆圈选中状态同步变化
      1. 图片切换,也即需要ul盒子偏移变化,通过设置变量num控制当前显示的图片索引
      2. 当切换到最后一张图片时,由于直接将图片索引num = 0,直接切换第一张会导致如下情况:
        js+html+css轮播图
        可以看出有明显的图片快速右移的现象,为了解决这种情况,采用无缝滚动原理:在图片最后添加第一张图片
        js+html+css轮播图
        当切换到最后一张图的时候,再次点击,ul父盒子偏移量变成第一个图片的偏移量,索引num = 0 再num + 1,再一定程度上实现似乎是由第一张图切换到第二张图片的效果。
 // 采取无缝滚动原理 num == ul.children.length - 1的原因是: 点击后图片为下一张图片,因此num 与 图片实际相差1
            if (num == ul.children.length - 1) {
                ul.style.left = 0;
                num = 0;
            }
            num++;
  1. 多次快速点击会导致图片未显示完便显示下一张,是的播放过快的情况,因此采用节流阀来解决以上情况
    1. 节流阀的目的:当上一个函数动画内容执行完毕,再去执行下一个函数动画,让函数无法连续触发
    2. 核心实现思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数
      1. 开始设置一个变量var flag = true;
      2. if(flag){flag = false;do something} 关闭水龙头
      3. 利用回调函数 动画执行完毕,flag = true 打开水龙头
  2. 自动播放
    1. 由于自动播放的实现原理与点击右箭头一样,因此只需要在定时器中手动调用右箭头点击事件即可
     //  自动播放轮播图
    var timer =  setInterval(function () {
       //  手动调用点击事件
       arrow_r.click();
    },2000)
    
实现代码

html

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>practice1</title>
    <link href="../css/practive1.css" rel="stylesheet"/>
    <script src="../js/animate.js"></script>
    <script type="text/javascript" src="../js/practice1.js"></script>
</head>

<body>
<div class="sildeshow">
<!--    左侧按钮-->
    <a href="javascript:;" class="arrow-l">⬅</a>
<!--    右侧按钮-->
    <a href="javascript:;" class="arrow-r">➡</a>
<!--    滚动区域-->
    <ul>
        <li>
            <a href="#"><img src="../imgs/OIP.jpg" alt="图片"></a>
        </li>
        <li>
            <a href="#"><img src="../imgs/green_bg.jpg" alt="图片"></a>
        </li>
        <li >
            <a href="#"><img src="../imgs/grils.png" alt="图片"></a>
        </li>
    </ul>
<!--    点击圆圈区域-->
    <ol class="circle"></ol>
</div>
</body>

</html>

css

ul,
ol {
    margin: 0;
    padding: 0;
    list-style-type: none;
}


.sildeshow {
    position: relative;
    margin: 0 auto;
    width: 760px;
    height: 400px;
    /*border: 1px solid #86c4d6;*/
    /*background-color: #999999;*/
    overflow: hidden;
}

.sildeshow ul {
    position: absolute;
    top: 0px;
    left: 0px;
    width: 400%;
    height: 100%;
}

.sildeshow ul li {
    float: left;
}

img {
    width: 760px;
    height: 400px;
}

a {
    text-decoration: none;
}

.arrow-l {
    display: none;
    position: absolute;
    top: 200px;
    left: 10px;
    font-size: 30px;
    color: #fff;
    z-index: 9;
}

.arrow-r {
    display: none;
    position: absolute;
    top: 200px;
    right: 10px;
    font-size: 30px;
    color: #fff;
    z-index: 9;
}
.circle {
    position: absolute;
    bottom: 10px;
    left: 50px;
    z-index: 9;
}

.circle li {
    float: left;
    width: 10px;
    height: 10px;
    /*background-color: #fff;*/
    border: 3px solid rgba(255, 255, 255, 0.5);
    margin: 0 3px;
    border-radius: 50%;
    /*鼠标经过显示小手*/
    cursor: pointer;
}

.current_circle {
    background-color: #fff;
}

js

window.addEventListener('pageshow',function () {
    var sildeshow = document.querySelector('.sildeshow');
    var arrow_l = document.querySelector('.arrow-l');
    var arrow_r = document.querySelector('.arrow-r');

    // 鼠标经过轮播图 显示隐藏左右箭头
    sildeshow.addEventListener('mouseenter',function () {
        arrow_l.style.display = 'block';
        arrow_r.style.display = 'block';
        // 终止计时器
        clearInterval(timer);
        timer = null;
    })

    sildeshow.addEventListener('mouseleave',function () {
        arrow_l.style.display = 'none';
        arrow_r.style.display = 'none';
        timer = setInterval(function () {
            //  手动调用计时器
            arrow_r.click();
        },2000);
    })

    // 动态生成小圆圈
    var ul = sildeshow.querySelector('ul');
    var ol = sildeshow.querySelector('.circle');
    for (var i = 0; i < ul.children.length; i++) {
        var li = document.createElement('li');
        // 绑定自定义属性Index
        li.setAttribute('data-index',i);
        ol.appendChild(li);
        // li标签绑定点击事件
        li.addEventListener('click',function () {
            for (var i = 0; i < ol.children.length; i++) {
                ol.children[i].className = '';
            }
            this.className = 'current_circle';
            //  点击小圆圈 切换图片
            var index = this.dataset.index;
            // 控制与左右箭头点击以及小圆圈显示同步
            num = index;
            circle = index;
            var sildeshowWidth = ul.querySelectorAll('img')[index].offsetWidth + 4;
            animate(ul,-index * sildeshowWidth,15);
        })
    }
    // 设置第一个小圆圈默认被选中
    if (ol.children[0]) {
        ol.children[0].className = 'current_circle';
    }

    // 右侧箭头点击注册事件
    var num = 0; // 控制显示图片次序
    // 克隆第一张图片 在生成小圆圈之后操作,不会引起多于小圆圈的产生
    var firstLi = ul.children[0].cloneNode(true);
    ul.appendChild(firstLi);
    // 控制小圆圈播放
    var circle = 0;
    // 节流阀
    var flag = true;
    arrow_r.addEventListener('click',function () {
        if (flag) {
            // 关闭节流阀
            flag = false;
            // 采取无缝滚动原理 num == ul.children.length - 1的原因是: 点击后图片为下一张图片,因此num 与 图片实际相差1
            if (num == ul.children.length - 1) {
                ul.style.left = 0;
                num = 0;
            }
            num++;
            var sildeshowWidth = ul.querySelectorAll('img')[num].offsetWidth + 4;
            animate(ul,-num * sildeshowWidth,15,function () {
                //  动画执行完毕,方可打开节流阀
                flag = true;
            });
            //  小圆圈播放设置
            circle++;
            circle = circle == ul.children.length - 1? 0 : circle;
            clearOlLi();
        }
    })

    // 左侧箭头点击注册事件
    arrow_l.addEventListener('click',function () {
        if (flag) {
            // 关闭节流阀
            flag = false;
            if (num == 0) {
                num = ul.children.length - 1;
                ul.style.left = - num * (ul.querySelectorAll('img')[num].offsetWidth + 4) + 'px';
            }
            num--;
            var sildeshowWidth = ul.querySelectorAll('img')[num].offsetWidth + 4;
            animate(ul,-num * sildeshowWidth,15,function () {
                // 只有当当前动画执行完毕,方可打开节流阀
                flag = true;
            });
            //  小圆圈播放设置
            circle--;
            circle = circle < 0? ol.children.length - 1 : circle;
            clearOlLi();
        }
    })

    //  自动播放轮播图
    var timer =  setInterval(function () {
        //  手动调用点击事件
        arrow_r.click();
    },2000)

    // 清除ol样式
    function clearOlLi() {
        //    排他思想清除其他样式
        for (var i = 0; i < ol.children.length; i++) {
            ol.children[i].className = '';
        }
        //    设置小圆圈的样式
        ol.children[circle].className = 'current_circle';
    }
})

涉及的animate函数见js动画函数实现侧边栏动态显示内容.

上一篇:对象下—练习4


下一篇:Mybatis表名为关键词时出现的错误