欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

原生JS简易轮播图

程序员文章站 2022-04-10 09:08:06
原生JS简易轮播图...

轮播图

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        ul,li{
            list-style: none;
        }
        .slider{
            width: 1130px;
            height: 286px;
            margin: 50px auto;
            position: relative;
            overflow: hidden;
        }
        .slider_img{
            width: 1130px;
            height: 286px;
        }
        .slider li{
            position: absolute;
            top: 0;
            left: 0;
            width: 1130px;
            height: 286px;
        }
        .slider li img{
            width: 100%;
            height: 100%;
        }
        .slider_btn{
            text-align: center;
        }
        .slider_btn .prev{
            background: url(https://static.zcool.cn/git_z/z/widget/slider/images/svg/left_arrow.svg?v=2);
            width: 52px;
            height: 52px;
            position: absolute;
            z-index: 100;
            top: 50%;
            margin-top: -26px;
            left: 10px;
            cursor: pointer;
        }
        .slider_btn .next{
            background: url(https://static.zcool.cn/git_z/z/widget/slider/images/svg/right_arrow.svg?v=2);
            width: 52px;
            height: 52px;
            position: absolute;
            z-index: 100;
            top: 50%;
            margin-top: -26px;
            right: 10px;
            cursor: pointer;
        }
        .xbtn{
            position: absolute;
            top: 93%;
            left: 50%;
            transform:translate(-50%,-50%);
        }
        .dot{
            display: inline-block;
            width: 15px;
            height: 15px;
            border: 1px solid yellow;
            border-radius: 50%;
            margin: 0 20px ;
            box-shadow: 0 0 5px black;
            cursor: pointer;
        }
        .dot_color{
            background-color: red;
        }
    </style>
</head>
<body>
    <div class="slider">
        <div class="slider_img">
            <ul>
                <li><a href="#"><img src="https://img.zcool.cn/community/01d6405f59b89111013e3187e86597.png@1380w" alt=""></a></li>
                <li><a href="#"><img src="https://img.zcool.cn/community/0102135f5c387111013e3187f5cafc.jpg@1380w" alt=""></a></li>
                <li><a href="#"><img src="https://img.zcool.cn/community/018a0a5f5c31f811013e3187ce23a5.jpg@1380w" alt=""></a></li>
                <li><a href="#"><img src="https://img.zcool.cn/community/01a6c05f599e5611013f1a647af2fc.jpg@1380w" alt=""></a></li>
                <li><a href="#"><img src="https://img.zcool.cn/community/015e555f5c394711013f1a64a7ea3f.jpg@1380w" alt=""></a></li>
                <li><a href="#"><img src="https://img.zcool.cn/community/01a2545f59b87e11013f1a645c4e01.png@1380w" alt=""></a></li>
                <li><a href="#"><img src="https://img.zcool.cn/community/0160515f59b8f311013f1a649a62bc.png@1380w" alt=""></a></li>
            </ul>
        </div>
        <div class="slider_btn">
            <span class="prev"></span>
            <span class="next"></span>
            <div class="xbtn">

            </div>
        </div>
    </div>
</body>
<script>

    /*
        需求分析:
            1 根据图片的数量自动生成小圆点(类名:dot)
            2 点亮第一个小圆点(当前小圆点:dot_color)
            3 显示第一个图片(li),其他里都放到右边(左边left:-容器宽度,右边left:容器宽度)
            4 点击小圆点显示相应的图片
            5 点击prev箭头,显示上一张
            6 点击next箭头,显示下一张
            7 轮播图会自动轮播
            8 鼠标移入slider盒子,停止轮播,鼠标移出slider盒子,继续轮播
    */

    //获取相关元素
    var slider = $id('.slider');//轮播图容器
    var WIDTH = slider.offsetWidth;//容器/图片的宽度
    var ImgArr = slider.children[0].children[0].children;//所有图片所在li的集合
    // console.log(ImgArr)
    var xbtn = $id('.xbtn')
    var slider_btn = slider.children[1];//轮播图控制按钮存放容器
    var prev_btn = $id('.prev');//上一张按钮
    var next_btn = $id('.next')
    var index = 0;//index是一个全局变量,记录当前显示的图片的索引

    for(var i=0 ; i<ImgArr.length ; i++){
        //建立小按钮节点
        var span = document.createElement('span');
        //给小按钮添加类名
        span.className = "dot";
        // span.innerHTML = i;
        span.index = i;//为了后期点击span的时候能够知道他是第几个
        //希望把span插入到xbtn的子元素
        xbtn.appendChild(span);


        //3 其他li都放到右边(左边left:-WIDTH,右边left:WIDTHpx)
        ImgArr[i].style.left = WIDTH + 'px';
    }
    
    //2 点亮第一个小圆点(当前小圆点:dot_color)
    var spanArr = xbtn.children;
    spanArr[index].className = "dot dot_color";
    //3 显示第一个li
    ImgArr[index].style.left = 0;

    //4 把小圆点,作用箭头的事件都委托给父元素slider_btn
    slider_btn.onclick = function(e){
        e = e||window.event;
        var target = e.target||e.srcElement;
        if(target.className=="prev"){
            console.log("你点击了上一张按钮");
            //如果当前图片索引是index,那么现在要看的索引是newIndex
            var newIndex = index-1;
            //如果newIndex<0,就是想看最后一张
            if(newIndex<0){
                newIndex = ImgArr.length-1;
            }
            //那么我要看的图一定在左边
            ImgArr[newIndex].style.left = -WIDTH + "px"
            //原来索引是index的图去右边
            animate(ImgArr[index],{left:WIDTH})
            //现在索引newIndex的图去中间
            animate(ImgArr[newIndex],{left:0});
            //更新最新的索引
            index = newIndex;
            //点亮小圆点
            light();
        }else if(target.className=="next"){
            console.log("你点击了下一张按钮")
            nextImg();
        }else if(target.className.indexOf("dot")>-1){
            console.log("你点击了小圆点,点击的小圆点的索引是"+target.index);
            //你要看的索引是newIndex
            var newIndex = target.index;
            //如果要看到索引newIndex>index,索引newIndex必须在右边
            if(newIndex>index){
                //索引是newIndex的图片必须在右边
                ImgArr[newIndex].style.left = WIDTH + "px";
                //原来索引是index的图去左边
                animate(ImgArr[index],{left:-WIDTH})
                //现在的索引是newIndex的图去中间
                animate(ImgArr[newIndex],{left:0})
            }
            //如果要看的索引newIndex<index,索引newIndex必须在左边
            else if(newIndex<index){
                //索引是newIndex的图片必须在左边
                ImgArr[newIndex].style.left = -WIDTH + "px"
                //原来索引是index的去右边
                animate(ImgArr[index],{left:WIDTH})
                //现在索引是newIndex的去中间
                animate(ImgArr[newIndex],{left:0})
            }
            //不管是newIndex<index还是newIndex>index,运动完以后都要更新索引index,并点亮小圆点
            index = newIndex;
            light();
        }
    }

    // 7 轮播图会自动轮播
    var timer = setInterval(nextImg,2000);
    document.onvisibilitychange = function(){
        if(document.visibilityState=="hidden"){
            clearInterval(timer)
        }
        if(document.visibilityState=="visible"){
            timer = setInterval(nextImg,2000);
        }
    }
    //8 鼠标移入slider盒子,停止轮播,鼠标移出slider盒子,继续轮播
    slider.onmouseenter = function(){
        clearInterval(timer);
    }
    slider.onmouseleave = function(){
        clearInterval(timer);
        timer = setInterval(nextImg,3000)
    }

    //点亮小圆点
    function light(){
        for(var i=0 ; i<ImgArr.length ;i++){
            //图片有几个,小圆点就有几个
            spanArr[i].className = "dot"
        }
        spanArr[index].className = "dot dot_color"
    }
    //显示下一张
    function nextImg(){
        //如果当前图片索引是index,那么现在要看的索引是newIndex
        var newIndex = +index + 1;//在这一个字符串前面写加号表示正号
        //如果newIndex>ImgArr.length-1
        if(newIndex>ImgArr.length-1){
            newIndex = 0;
        }
        //那么我要看的图一定在右边
        ImgArr[newIndex].style.left = WIDTH + "px";
        //原来索引index的图片去左边
        //现在索引newIndex的图片去中间
        animate(ImgArr[index],{left:-WIDTH})
        animate(ImgArr[newIndex],{left:0})
        //更新当前索引index
        index = newIndex;
        //点亮小圆点
        light();
    }
    //获取元素
    function $id(id){
    return document.querySelector(id)
}
function $ids(id){
    return document.querySelectorAll(id)
}
//获取指定dom的指定样式值 dom:元素 , attr:要获取的属性
function getStyle(dom,attr){
    if(window.getComputedStyle){
        return window.getComputedStyle(dom,null)[attr];
    }else{
        return dom.currentStyle[attr]
    }
}
/* 
    animate:让指定元素的多属性同时缓动到指定目标
        ==>参数1:dom 要缓动的元素节点
        ==>参数2:json 动画属性:属性值的目标值
            {
                width:400,
                height:500,
                left:100,
                top:300,
            }
        ==>参数3:fn 动画完成以后执行的函数
*/
function animate(dom,json,fn){
    clearInterval(dom.timer)
    //每隔一段时间,json里面的每个属性都变化一点
    dom.timer = setInterval(function(){
        //每次运动开始
        var flag = true; //如果后面有哪个属性值没有达到目标属性值,就把flag变成false
        //json里面有几个键值对,就要运动几次
        for(var attr in json){
            //1 获取当前位置
            if(attr == "opacity"){
                var current = parseInt(getStyle(dom,attr)*100)
            }else{
                var current = parseInt(getStyle(dom,attr))
            }

            //2 计算速度
            var target = parseInt(json[attr]);
            var speed = target>current?Math.ceil((target-current)/10):Math.floor((target-current)/10)

            //3 计算下一次位置
            if(attr == "zIndex"){
                var next = target;//如果缓动的属性是zIndex,直接一步到位,不用缓动
            }else{
                var next = current + speed;
            }

            //4 定位元素
            if(attr == "opacity"){
                dom.style.opacity = next/100;
                dom.style.filter = "alpha(opacity="+next+")"
            }else if(attr == "zIndex"){
                dom.style.zIndex = next;
            }else{
                dom.style[attr] = next + "px";
            }
            if(next != target){
                flag = false;
            }
        }
        //本次运动结束,检查flag的值
        if(flag){
            clearInterval(dom.timer);
            if(fn){
                fn()
            }
        }
    },1000/60)
}
</script>
</html>

本文地址:https://blog.csdn.net/Bob_Yan623/article/details/109254027