一直想自己动手做一个图片轮播的控件,查查网上的资料大多引用已经做好的组件,其原理算法不是很清楚,于是自己用jquery写了一个.先看下效果图:

           主要界面实现思路如下:

   1.新建一个div宽度为100%,flex布局,主要是为了网页主体内容居中,和留白部分的进一步处理
2.新建div,为网页的内容宽度,设置为1200px
3.图片轮播窗口,宽度,高度为300px,overflow:hidden
4.轮播窗口新建ul>li>img,ul采用position:relative
5.li样式 border-radius:150px主要是制作圆形视图
6.同ul同级,新建div>span 当前图片页码,position:relative,span border-radius:10px,圆形
7.将当前图片页码定位到图片视窗内

         图片轮播设计思路:

   1.在录播窗口以jq动画 animate移动ul
   2.在ul的起始位置插入(insertBefore)最后一个元素的clone,$('ul li:nth-child(7)').clone(),在ul的最后一个追加(insetAfter)
     第一个元素$('ul li:nth-child(7)').clone(),这时比如,list中有7个元素,经过追加之后,有9个元素,(这么做主要是为了ul在向左或
     者向右移动之后,视觉上一连续切换到最后一个,或者第一个)
   3.点击向左/向右,向左向右每次移动一个img的宽度(300px)
   3.如果当前展示的img是第一个,再向左移动一个,连续展示我们插入的最后一个元素,然后迅速将ul定位到img的倒数第二个元素,反之定位到第二
     个元素,这样就实现了一个循环轮播
   4.最后设置,展示的图片和图片页码对应的样式
   5.设计逻辑,比如点击了向左,每隔5秒自动播放的时候,也是向左播放,页码切换的时候是向左切换,自动播放也将切到向左,反之亦然

  

           下面是页面代码:     

<html>
<head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
    <title>图片轮播</title>
    <script src="./javascript/jquery.min.js"></script>
    <style type="text/css">
        * {
            text-decoration: none;
            list-style: none;
            margin: 0;
            padding: 0;
            font-size: 14px;
            letter-spacing: 1px;
            color: #000;
            background: none;
        }
        .window-content ul {
            width: 5000px;
            display: flex;
            text-wrap: none;
            white-space: nowrap;
            position: relative;
        }

        .window-content ul li div {
            line-height: 300px;
        }

        .window-content ul li {
            float: left;
            border-radius: 150px 150px 150px 150px;
            overflow: hidden;

        }

        .window-content {

            width: 300px;
            height: 300px;
            overflow: hidden;
            background: none;
            border: 1px solid #ededed;
            border-radius: 150px;
        }

        .window {
            width: 100%;
            height: 340px;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-direction: column;
            background: #f4f4f4;
        }

        .window-wrap {
            flex: 1;
            width: 1200px;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-direction: row;
            background: #e0e0e0;
        }
        .window-index
        {
            position: relative;
            top: -19px;
            left: 101px;
            margin: -20px;
        }
        .window-index .content-index
        {
            text-align: center;
            line-height: 20px;
            font-size: 12px;
            width: 20px;
            height: 20px;
            color: black;
            display: inline-block;
            border: 1px solid antiquewhite;
            background: white;
            margin:-3px;
            border-radius: 10px;
        }
        .window-index .content-index:hover
        {
            cursor: pointer;
        }
        .selected:hover
        {
            cursor: pointer;
        }
        .selected
        {
            text-align: center;
            line-height: 20px;
            font-size: 12px;
            width: 20px;
            height: 20px;
            display: inline-block;
            border: 1px solid antiquewhite;
            margin:-3px;
            border-radius: 10px;
            background: #9e0909;
            color: white;
        }

    </style>
    <script>
        class PicMove {
            constructor() { 
                //录播图片容器
                this._parent = $('.window-content ul');
                //容器中图片的起始个数
                this._elmentcount = this._parent.children().length;
                //起始第一个元素
                this._head = this._parent.children(':nth-child(1)');
                //起始最后一个元素,nth-child下标是从1开始的
                this._tail = this._parent.children(':nth-child(' + this._elmentcount + ')');
                //当前轮播窗口,图片的下标(页码)
                this._arrowflag = 1;
                //播放的方向,默认是向右
                this.isRunRight = true;
                //主要是成员函数中用到了this,为了防止发生异常,对成员函数中的this进行绑定
                this.RunLeft = this.RunLeft.bind(this);
                this.RunRight = this.RunRight.bind(this);
                this.LeftStop=this.LeftStop.bind(this);
                this.RightStop=this.RightStop.bind(this);
                this.Move=this.Move.bind(this);
                this.autoMove=this.autoMove.bind(this);
                this.auToRun=this.auToRun.bind(this);
                this.showIndex=this.showIndex.bind(this);
                //自动轮播的计时器
                this.Interval=null;
            }
            //启动自动播放
            autoMove()
            {   
                //启动自动播放之前,清除掉历史的,要不然播放的速度或者次序可能会乱,整个界面只保留一个有效的计时器
                if(this.Interval) {
                    clearInterval(this.Interval);
                } 
                //设置每隔5秒,左播放,或者右播放
                this.Interval=setInterval(this.auToRun,5000);
            }
            //执行向左或者向右轮播动作
            auToRun()
            {
                if(this.isRunRight===true)
                {
                    this._parent.animate({'left': '-=300px'}, 300, ()=>{
                     //动画执行完成的,回调函数使用箭头函数,主要是里面也有this,并且this期望指向当前类的实例,而不是调用环境,和在构造中bind成员函数的效果是一样的
                        //页码加
                        this._arrowflag++;
                        if (this._arrowflag > this._elmentcount) {
                            //右播放到最后一个,应该从第一个开始,所以这里瞬间定位到第二张图片的位置(第一张图片是克隆的最后一站图片),图片都是一样的,感官没有觉察
                            this._parent.css({'left': '-300px'});
                            this._arrowflag = 1;
                        }
                        //播放完成设置页码样式
                        this.showIndex();
                    });
                }
                else
                {
                       this._parent.animate({'left': '+=300px'}, 300, ()=>{
                        this._arrowflag--;
                        if (this._arrowflag < 1) {

                            this._parent.css({'left': -(300 * this._elmentcount) + 'px'});
                            this._arrowflag = this._elmentcount;
                        }
                        this.showIndex();
                    });
                }
            }
            //设置页码样式
            showIndex()
            {
                $(".selected").removeClass("selected").addClass("content-index");
                $(".content-index:nth-child("+ this._arrowflag+")").removeClass("content-index").addClass("selected");
            } 
            //页面加载完成初始化,图片轮播控件
            init() {
                this._tail.clone().insertBefore(this._head);
                this._head.clone().insertAfter(this._tail);
                //初始定位到this.head元素的位置,这个是起始位置
                this._parent.css('left', '-300px');
                //向右按钮事件
                $('.run-right').click(this.RunRight);
                $('.run-left').click(this.RunLeft);
                //页码被hove,时执行的操作
                $('.content-index').hover((e)=>{
                     let thisEle=$(e.target);
                     let index=Number.parseInt(thisEle.html());
                   //这里,主要是为了测试在鼠标hover的时候,响应函数被执行了几次
                    //console.log(`${this._arrowflag}-->${index}`);
                     //视窗图片,展示指定页码的图片
                     this.Move(index);
                     //thisEle.removeClass("content-index")
                     //thisEle.addClass("selected");
                     this.showIndex();
                });
                this.showIndex();
               this.autoMove();
            }
            //这个函数主要是,向左移动一次之后,回调设置成员的值,设置初始化循环播放
            LeftStop() {
                this._arrowflag--;
                this.isRunRight = false;
                if (this._arrowflag < 1) {
                    this._parent.css({'left': -(300 * this._elmentcount) + 'px'});
                    this._arrowflag = this._elmentcount;
                }
                this.showIndex();
                this.autoMove();
            }
            //向左按钮事件,函数
            RunLeft() {
                clearInterval(this.Interval);
                this._parent.stop(true,true);
                this._parent.animate({'left': '+=300px'}, 300, this.LeftStop)
            }
//这个函数主要是,向右移动一次之后,回调设置成员的值,设置初始化循环播放,由于有this,所以这么定义

            RightStop() {
                this._arrowflag++;
                this.isRunRight = true;
                if (this._arrowflag > this._elmentcount) {
                    this._parent.css({'left': '-300px'});
                    this._arrowflag = 1;
                }
                this.autoMove();
                this.showIndex();
            }
          //向右按钮事件
            RunRight() {
                clearInterval(this.Interval);
                //鼠标hover,很快可能定义的动画还没执行完,就开始响应下一次移动,会造成混乱,这里提前结束每个动画,并且停在动画的终点
                this._parent.stop(true,true);
                this._parent.animate({'left': '-=300px'}, 300, this.RightStop)
            }
            //页码hover的时候,移动的函数
            Move(index) {

                let current=this._arrowflag;
                this._arrowflag=index;
                  if (index<current)//左移
                  {
                      this.isRunRight = false;
                      var count=current-index;
                      this._parent.stop(true,true);
                     this._parent.animate({'left': '+='+(300*count)+'px'}, 300, ()=>{
                          this.autoMove();
                      });
                      this.showIndex();
                  }
                  else if(index>current)//右移
                  {
                      this.isRunRight = true;
                      var count=index-current;
                      this._parent.stop(true,true);
                      this._parent.animate({'left': '-='+(300*count)+'px'}, 300, ()=>{
                          this.autoMove();
                          this.showIndex();
                      });
                  }
            }
        }
        $(function () {
            //页面加载完成,初始化图片轮播控件
            let picmove = new PicMove();
            picmove.init();
        });

    </script>
    <script src="javascript/jquery.transit.js"></script>
</head>
<body>

<div class="window">
    <div class="window-wrap">
        <span class="run-left">向左</span>
        <div class="window-content">
            <ul>
                <li>
                    <div style="background-image: url('./images/show-window/1.jpg');background-size: cover;width: 300px;height: 300px">
                        1
                    </div>
                </li>
                <li>
                    <div style="background-image: url('./images/show-window/3.jpg');background-size: cover;width: 300px;height: 300px">
                        2
                    </div>
                </li>
                <li>
                    <div style="background-image: url('./images/show-window/4.jpg');background-size: cover;width: 300px;height: 300px">
                        3
                    </div>
                </li>
                <li>
                    <div style="background-image: url('./images/show-window/5.jpg');background-size: cover;width: 300px;height: 300px">
                        4
                    </div>
                </li>
                <li>
                    <div style="background-image: url('./images/show-window/6.jpg');background-size: cover;width: 300px;height: 300px">
                        5
                    </div>
                </li>
                <li>
                    <div style="background-image: url('./images/show-window/7.jpg');background-size: cover;width: 300px;height: 300px">
                        6
                    </div>
                </li>
                <li>
                    <div style="background-image: url('./images/show-window/8.jpg');background-size: cover;width: 300px;height: 300px">
                        7
                    </div>
                </li>
            </ul>
            <div class="window-index">
                <span class="content-index">1</span>
                <span class="content-index">2</span>
                <span class="content-index">3</span>
                <span class="content-index">4</span>
                <span class="content-index">5</span>
                <span class="content-index">6</span>
                <span class="content-index">7</span>
            </div>
        </div>
        <span class="run-right">向右</span>
    </div>
</div>
</body>
</html>

 

 

          才开是学习前端,代码有需要重构的地方,比如页码hover的逻辑,也向左向右按钮的事件代码有重复,自动轮播的时间间隔,可以拎出来单独配置,以后要改时间就改一个变量的值就可以了,flex布局在IE上不支持,没有做浏览器适配等

 

          希望指正!