轮播图动画滑动动画效果

轮播图的实现原理并不难,但是步骤有些繁琐。最近练习了一个轮播图,大部分是跟着网上的教程写的,然后自己做了一点兼容ie8的修改,加了点击切换图片的特效和手机端的滑动特效,让这个轮播图可以在响应式的网站中使用,同时兼容pc端和触屏端。

轮播图的样式也分很多种,淡入淡出的轮播图很容易实现,只需要把图片全都叠在一起,让相应的图片轮流显示就行了,但是滚动能的轮播图就要复杂很多。这里介绍的是滚动的轮播图:

原理:

实现的原理就是将所有的图片横向的排列起来,排成一个长方形,让这个长方形的总体不断平移,从而使图片轮流显示在div中,然后将div之外的隐藏起来就可以了

下面是详细步骤:

第一步,基本框架

1)将要轮播的所有的图片都放到一个无序列表中

<div id="outer">
            <ul id="imgList">
                <li><img src="img/1.jpg"/></li>
                <li><img src="img/2.jpg"/></li>
                <li><img src="img/3.jpg"/></li>
                <li><img src="img/4.jpg"/></li>
                <li><img src="img/5.jpg"/></li>
            </ul>
        </div

2)所有的li标签左浮动,只要ul的宽度够大,所有的图片就会横向的排列起来。

#imgList>li{
float: left;
}

3)让图片的宽高等于div的宽高,这样做不但能够提高开发的效率,还更便于网站的维护,即使轮播的图片尺寸都是不一样的,也能正常显示:

</p> 
 <div class="cnblogs_code"> 
  <pre><span style="color:#0000ff;">//getCompteredStyle方法和current方法作用相同,都是获取dom对象的属性,前者不兼容ie8,后者不兼容firefox,这样写可以解决兼容性的问题。<br>function</span><span style="color:#000000;"> getStyle(obj, name) {
                    </span><span style="color:#0000ff;">if</span><span style="color:#000000;">(window.getComputedStyle) {
                        </span><span style="color:#0000ff;">return</span> getComputedStyle(obj, <span style="color:#0000ff;">null</span><span style="color:#000000;">)[name];
                    } </span><span style="color:#0000ff;">else</span><span style="color:#000000;"> {
                        </span><span style="color:#0000ff;">return</span><span style="color:#000000;"> obj.currentStyle[name];
                    }
                }
</span><span style="color:#008000;">//</span><span style="color:#008000;">-- 获取outer的宽度</span>
<span style="color:#0000ff;">var</span> getOuterWidth = getStyle(outer,"width"<span style="color:#000000;">);<br><span style="color:#008000;">//去掉获取到的宽度值的px,使成为number类型的变量,方便计算
</span></span><span style="color:#0000ff;">var</span> widthObject = getOuterWidth.match(/\d*/<span style="color:#000000;">);
</span><span style="color:#0000ff;">var</span> width = widthObject[0];</pre> 
 </div> 
 <p>&nbsp;</p> 
 <p>&nbsp;</p> 

第二步,添加几个导航点和两个按钮

<div class="cnblogs_code"> 
  <pre>&lt;div id="navContainer"&gt;<br>          <span style="color:#008000;">&lt;!--我们就是导航点 --&gt;</span>
                &lt;a href="javascript:;"&gt;&lt;/a&gt;
                &lt;a href="javascript:;"&gt;&lt;/a&gt;
                &lt;a href="javascript:;"&gt;&lt;/a&gt;
                &lt;a href="javascript:;"&gt;&lt;/a&gt;
                &lt;a href="javascript:;"&gt;&lt;/a&gt;
            &lt;/div&gt;<br>       <span style="color:#008000;">&lt;!--我们是左右切换按钮--&gt;</span>
            &lt;a href="javascript:;" id="picLbtn"&gt;&lt;img src="img/pic/picLbtn.png"&gt;&lt;/a&gt;
            &lt;a href="javascript:;" id="picRbtn"&gt;&lt;img src="img/pic/picRbtn.png"&gt;&lt;/a&gt;</pre> 
 </div> 

 1)这里的圆点使用a标签来做,a标签为内联元素,是不能调整大小的。这里使用float:left给他设置为右浮动之后他就会转化为块级元素。当然,直接使用display:block也是可以的:

<div class="cnblogs_code"> 
  <pre>#navContainer&gt;<span style="color:#000000;">a{
                z</span>-index: 5<span style="color:#000000;">;
                </span><span style="color:#0000ff;">float</span><span style="color:#000000;">: left;
                width: 15px;
                height: 15px;
                background</span>-<span style="color:#000000;">color: red;
                margin: </span>0<span style="color:#000000;"> 5px;
                opacity: </span>0.5<span style="color:#000000;">;
                filter: alpha(opacity</span>=50<span style="color:#000000;">);
                border</span>-radius: 100%<span style="color:#000000;">;
            }</span></pre> 
 </div> 

这里把a标签的数量写固定了,如果上面放置了十张图片轮播,下面就要写十个导航点。

可以根据图片的数量动态的设置a标签的数量,不过这样写意义不大:

<div class="cnblogs_code"> 
  <pre>获取所有的imgList中所有的li标签放在对象x中,<br>for(i=0,i&lt;x.length-1){<!-- --><br>x.appendchild(a)//每次循环向数组中添加一个<br>}<br>a.href=javascript:;</pre> 
 </div> 

 2)添加两张图片作为向左向右切换的按钮,这种图片很多网站都有,如果不会ps的话随便找个带轮播图的网站占下来就可以用

3)导航点和轮播图的位置要继承div的位置,并且要动态的设置:

<div class="cnblogs_code"> 
  <pre><span style="color:#008000;">//(大div的宽度 - 导航区域的宽度)/ 2 = 导航区域的左边距</span><br>navContainer.style.left = (outer.offsetWidth - navContainer.offsetWidth)/2 + "px";</pre> 
  <pre><span style="color:#008000;">//(大div的高度 - 按钮区域的高度)/ 2 = 按钮区域的上边距</span></pre> 
  <pre><span style="color:#0000ff;">var</span> tempBtnTop = (outer.offsetHeight - picLbtn.offsetHeight)/2 + "px"; picLbtn.style.top =<span style="color:#000000;"> tempBtnTop; picRbtn.style.top </span>= tempBtnTop;</pre> 
 </div> 

这样,这样不管大div改成多大,都不需要修改图片和导航点的定位,这个思想后面会多次体现。

第三步,自动切换图片

1)这里需要写一个move函数,作用是设置ul移动的平移效果。调用该函数时需要传递四个参数:要执行动画的对象,执行对象的属性,执行对象的目标,速度,回调函数

<div class="cnblogs_code"> 
  <pre><span style="color:#0000ff;">function</span><span style="color:#000000;"> move(obj, attr, target, speed, callback){
                    </span><span style="color:#008000;">//</span><span style="color:#008000;">关闭上一个定时器</span>
<span style="color:#000000;">                    clearInterval(obj.timer);
                    </span><span style="color:#008000;">//</span><span style="color:#008000;">获取元素目前的位置</span>
                    <span style="color:#0000ff;">var</span> current =<span style="color:#000000;"> parseInt(getStyle(obj, attr));
                    </span><span style="color:#008000;">//</span><span style="color:#008000;">判断速度的正负值</span>
                    <span style="color:#008000;">//</span><span style="color:#008000;">如果从0 向 800移动,则speed为正</span>
                    <span style="color:#008000;">//</span><span style="color:#008000;">如果从800向0移动,则speed为负</span>
                    <span style="color:#0000ff;">if</span>(current &gt;<span style="color:#000000;"> target) {
                        </span><span style="color:#008000;">//</span><span style="color:#008000;">此时速度应为负值</span>
                        speed = -<span style="color:#000000;">speed;
                    }
                    </span><span style="color:#008000;">//</span><span style="color:#008000;">开启一个定时器,用来执行动画效果</span>
                    <span style="color:#008000;">//</span><span style="color:#008000;">向执行动画的对象中添加一个timer属性,用来保存它自己的定时器的标识</span>
                    obj.timer = setInterval(<span style="color:#0000ff;">function</span><span style="color:#000000;">(){
                        </span><span style="color:#008000;">//</span><span style="color:#008000;">获取box1的原来的left值</span>
                        <span style="color:#0000ff;">var</span> oldValue =<span style="color:#000000;"> parseInt(getStyle(obj, attr));
                        </span><span style="color:#008000;">//</span><span style="color:#008000;">在旧值的基础上增加</span>
                        <span style="color:#0000ff;">var</span> newValue = oldValue +<span style="color:#000000;"> speed;
                        </span><span style="color:#008000;">//</span><span style="color:#008000;">判断newValue是</span><span style="color:#008000;">否</span><span style="color:#008000;">大于800</span>
                        <span style="color:#008000;">//</span><span style="color:#008000;">从800 向 0移动</span>
                        <span style="color:#008000;">//</span><span style="color:#008000;">向左移动时,需要判断newValue是否小于target</span>
                        <span style="color:#008000;">//</span><span style="color:#008000;">向右移动时,需要判断newValue是否大于target</span>
                        <span style="color:#0000ff;">if</span>((speed &lt; 0 &amp;&amp; newValue &lt; target) || (speed &gt; 0 &amp;&amp; newValue &gt;<span style="color:#000000;"> target)) {
                            newValue </span>=<span style="color:#000000;"> target;
                        }
                        </span><span style="color:#008000;">//</span><span style="color:#008000;">将新值设置给box1</span>
                        obj.style[attr] = newValue + "px"<span style="color:#000000;">;
                        </span><span style="color:#008000;">//</span><span style="color:#008000;">当元素移动到0px时,使其停止执行动画</span>
                        <span style="color:#0000ff;">if</span>(newValue ==<span style="color:#000000;"> target) {
                            </span><span style="color:#008000;">//</span><span style="color:#008000;">达到目标,关闭定时器</span>
<span style="color:#000000;">                            clearInterval(obj.timer);
                            </span><span style="color:#008000;">//</span><span style="color:#008000;">动画执行完毕,调用回调函数</span>
                            callback &amp;&amp;<span style="color:#000000;"> callback();
                        }
                    }, </span>30<span style="color:#000000;">);
                }</span></pre> 
 </div> 

2)自动轮播效果主要由autoChange函数实现,index变量再0到(imgArr.length - 1)之间不断循环,就实现了图片从一直循环展示

将偏移量设置为(-width*index),index函数每次都是累加的,这样每次的偏移量都是width的值,也就是图片的宽度

这段代码方放在setInterval函数中,setInterval函数的时间参数就是轮播图的轮播速度

<div class="cnblogs_code"> 
  <pre><span style="color:#0000ff;">function</span><span style="color:#000000;"> autoChange(){
                    </span><span style="color:#008000;">//</span><span style="color:#008000;">--这个定时器可以控制图片停留的时间</span>
                    <span style="color:#008000;">//</span><span style="color:#008000;">--每隔三秒执行一次,不断的被执行图片就不断切换</span>
                    timer = setInterval(<span style="color:#0000ff;">function</span><span style="color:#000000;">(){
                        index</span>++<span style="color:#000000;">;</span>
                        <span style="color:#008000;">//</span><span style="color:#008000;">--index对长度取余,就可以让index一直在范围内循环</span>
                        index %=<span style="color:#000000;"> imgArr.length;
                        </span><span style="color:#008000;">//</span><span style="color:#008000;">--这个move实现自动切换的平移效果</span>
                        move(imgList , "left" , -width*index , 20 , <span style="color:#0000ff;">function</span><span style="color:#000000;">(){
                            </span><span style="color:#008000;">//</span><span style="color:#008000;">--执行move函数时调用set方法,将图片颜色改变,并且首末过渡</span>
<span style="color:#000000;">                            setA();
                            setRed();
                        });
                    },</span>3000<span style="color:#000000;">);
                }</span></pre> 
 </div> 

3)从最后一张图片到第一张需要一个过渡效果,就是前面原理图中的首尾相连

首先要在最后一张的图片中再添加第一张图片

 <div class="cnblogs_code"> 
  <pre>&lt;ul id="imgList"&gt;
                &lt;li&gt;&lt;img src="img/pic/1.jpg"/&gt;&lt;/li&gt;
                &lt;li&gt;&lt;img src="img/pic/2.jpg"/&gt;&lt;/li&gt;
                &lt;li&gt;&lt;img src="img/pic/3.jpg"/&gt;&lt;/li&gt;
                &lt;li&gt;&lt;img src="img/pic/4.jpg"/&gt;&lt;/li&gt;
                &lt;li&gt;&lt;img src="img/pic/5.jpg"/&gt;&lt;/li&gt;
                &lt;li&gt;&lt;img src="img/pic/1.jpg"/&gt;&lt;/li&gt;
            &lt;/ul&gt;</pre> 
 </div> 

然后加一个判断,当执行的最后一张时,让他index立即变成0,当前显示的图片也会由最后一张变成第一张,而且因为最后一张和第一张时完全相同的,所以这个改变也是看不出来的,但是因为索引改变了,其他的也就跟着变成第一张了,再次自动循环的时候,就会自动变成第二张了。

<div class="cnblogs_code"> 
  <pre><span style="color:#0000ff;">function</span><span style="color:#000000;"> setA(){
                    </span><span style="color:#008000;">//</span><span style="color:#008000;">判断当前索引是否是最后一张图片</span>
                    <span style="color:#0000ff;">if</span>(index &gt;= imgArr.length - 1<span style="color:#000000;">){
                        </span><span style="color:#008000;">//</span><span style="color:#008000;">--如果当前图片是最后一张,将该图片立即变为第一张</span>
                        index = 0<span style="color:#000000;">;</span>
                        imgList.style.left = 0<span style="color:#000000;">;
                    }
                }</span></pre> 
 </div> 

 

4)改变下面导航点的颜色,循环到哪个图片,对应的导航点就会变成黑色,其他的则为红色:

<div class="cnblogs_code"> 
  <pre><span style="color:#0000ff;">function</span><span style="color:#000000;"> setRed(){
                    </span><span style="color:#0000ff;">for</span>(<span style="color:#0000ff;">var</span> i=0 ; i&lt;allA.length ; i++<span style="color:#000000;">){
                        </span><span style="color:#008000;">//</span><span style="color:#008000;">--去掉内联样式里的颜色,显示样式表里的红色</span>
                        <span style="color:#008000;">//</span><span style="color:#008000;">--如果这里不这么写的话,他就会每次遍历到某个图片,就会把他的导航点变成黑色,不会变回来</span>
                        <span style="color:#008000;">//</span><span style="color:#008000;">--这么写每次调用都会先把大家都变成红色,再把需要的变成黑色</span>
                        allA[i].style.backgroundColor = ""<span style="color:#000000;">;
                    }
                    allA[index].style.backgroundColor </span>= "black"<span style="color:#000000;">;
                }</span></pre> 
 </div> 

第四步,点击导航点切换图片

1)写一个for循环,0到长度减1赋值给allA对象的num属性,这样每个导航点都对应着一个下标:

<p><img src="https://img2018.cnblogs.com/blog/1674722/201905/1674722-20190525200629146-1697121741.png" alt=""></p> 

 

2)当点击导航点时,触发事件,将index设置为当前的num值,在执行move函数,他的偏移量就是改变后的-width * index,图片就会跳转到当前导航点对应的图片,具体代码如下:

<div class="cnblogs_code"> 
  <pre><span style="color:#0000ff;">var allA = document.querySelectorAll("#navContainer&gt;a");<br>for</span>(<span style="color:#0000ff;">var</span> i=0; i&lt;allA.length ; i++<span style="color:#000000;">){
                    </span><span style="color:#008000;">//</span><span style="color:#008000;">为每一个超链接都添加一个num属性</span>
                    allA[i].num =<span style="color:#000000;"> i;
                    allA[i].onclick </span>= <span style="color:#0000ff;">function</span><span style="color:#000000;">(){
                        </span><span style="color:#008000;">//</span><span style="color:#008000;">--在点击时,要关闭自动切换的定时器</span>
<span style="color:#000000;">                        clearInterval(timer);
                        </span><span style="color:#008000;">//</span><span style="color:#008000;">--获取点击超链接的索引,并将其设置为index</span>
                        index = <span style="color:#0000ff;">this</span><span style="color:#000000;">.num;
                        </span><span style="color:#008000;">//</span><span style="color:#008000;">--setA只控制导航点时的效果</span><span style="color:#000000;">
                        setRed();
                        </span><span style="color:#008000;">//</span><span style="color:#008000;">这个move是实现点击切换的平移效果,每次调用只会执行一次</span>
                        <span style="color:#008000;">//</span><span style="color:#008000;">--四个参数:要执行动画的对象,执行对象的属性,执行对象的目标,速度,回调函数</span>
                        move(imgList , "left" , -width*index , 20 , <span style="color:#0000ff;">function</span><span style="color:#000000;">(){
                            </span><span style="color:#008000;">//</span><span style="color:#008000;">开启被上面clearInterval关闭的自动切换程序</span>
<span style="color:#000000;">                            autoChange();
                        });
                    }</span></pre> 
 </div> 

 在执行单击触发函数时要用clearInterval把自动切换图片的定时器timer关掉,不然单击切换图片和自动切换图片同时执行网页会非常混乱。

同时也要调用setA函数,要将当前点击的图片设置为导航点变为黑色。

第五步,点击左右按钮切换图片

1)关闭timer定时器

2)左边的点击按钮是显示当前图片左边的图片,右边的点击按钮是显示当前图片右边的图片。因此要进行如下判断:

    如果当前是第一张:左边的点击按钮不工作

    如果是当前是最后一张:右边的点击按钮不工作(为了方便理解,和代码中的是反着写的)

3)完成判断后,调用setA函数设置导航点的颜色,然后开启正常的循环:


```javascript
<div class="cnblogs_code"> 
  <pre>picLbtn.onclick = <span style="color:#0000ff;">function</span><span style="color:#000000;">(){
                    clearInterval(timer);
              </span> <span style="color:#0000ff;">if</span> (index != 0<span style="color:#000000;">){
                        index </span>= index-1<span style="color:#000000;">;
                    }
                    setRed();
                    move(imgList , </span>"left" , -width*index , 20 , <span style="color:#0000ff;">function</span><span style="color:#000000;">(){
                        autoChange();
                    });
                }<br>picRbtn.onclick </span>= <span style="color:#0000ff;">function</span><span style="color:#000000;">(){
                    clearInterval(timer);</span>
                        <span style="color:#0000ff;">if</span> (index != allA.length - 1<span style="color:#000000;">) {
                            index </span>= index+1<span style="color:#000000;">;
                        }
                        setRed();
                        move(imgList , </span>"left" , -width*index , 20 , <span style="color:#0000ff;">function</span><span style="color:#000000;">(){
                            autoChange();
                        });
                    }
                }</span></pre> 
 </div> 

 <h1><a name="t6"></a><a name="t6"></a><strong>第六步,滑动屏幕切换图片</strong></h1> 
 <p><span style="color:#ff0000;"><strong>这个滑动效果只有在手机端电脑端或者打开浏览器的toggle device toobar模式才能用,光用鼠标拖拽是没有用的!!</strong></span></p> 
 <p>1)定义4个变量,用来存放一些数值:</p> 
 

```javascript
<div class="cnblogs_code"> 
  <pre><span style="color:#0000ff;">var</span> startX = 0; <span style="color:#008000;">//</span><span style="color:#008000;">记录起始  刚刚触摸的点的位置 x的坐标</span>
<span style="color:#0000ff;">var</span> moveX = 0;  <span style="color:#008000;">//</span><span style="color:#008000;">滑动的时候x的位置</span>
<span style="color:#0000ff;">var</span> distanceX = 0;  <span style="color:#008000;">//</span><span style="color:#008000;">滑动的距离</span>
<span style="color:#0000ff;">var</span> isMove = <span style="color:#0000ff;">false</span>;<span style="color:#008000;">//是否滑动了</span></pre> 
 </div> 
 <p>2)定义手指触摸屏幕触发函数:</p> 
 <p>在手指触摸到屏幕时,将触摸点的横坐标保存到startX变量中:</p> 
 <div class="cnblogs_code"> 
  <pre>outer.addEventListener('touchstart', <span style="color:#0000ff;">function</span><span style="color:#000000;">(e){
      clearInterval(timer);</span>
      startX = e.touches[0].clientX;  <span style="color:#008000;">//</span><span style="color:#008000;">--触摸点的横坐标</span>
});</pre> 
 </div> 

3)定义手指滑动触发函数:

touchmove事件是手指触摸在屏幕上就一直触发的,因此distanceX函数最终保存的值将是手指离开屏幕时的值,用这个值减去startX就是滑动的距离:

这里传递给move函数的偏移量值是(-width*index + distanceX),因此ul偏移的宽度是distanceX,就实现了图片跟随手指滑动的效果:

 <div class="cnblogs_code"> 
  <pre>outer.addEventListener('touchmove',<span style="color:#0000ff;">function</span><span style="color:#000000;">(e){e
     moveX </span>= e.touches[0].clientX;<span style="color:#008000;">//</span><span style="color:#008000;">--获取手指当前接触屏幕位置的横坐标</span>
     distanceX = moveX - startX; <span style="color:#008000;">//</span><span style="color:#008000;">--移动的距离=现在-初始</span>
     isMove = <span style="color:#0000ff;">true</span>;
     move(imgList , "left" , -width*index+distanceX , 20 , <span style="color:#0000ff;">function</span><span style="color:#000000;">(){});
});</span></pre> 
 </div> 

 4)定义手指离开屏幕触发函数

用div的宽度除以3(记作x),比较用刚才获得的滑动的距离(记作y)。

如果y > x,认为滑动有效

   如果往左滑就是切右边的图

   如果往右滑就是切左边的图

如果y < x,认为滑动的距离太短了,滑动无效,吸附回去

当前如果是第一张,还往右滑,或者是最后一张还能往左滑,同样认为滑动无效,吸附回去

<div class="cnblogs_code"> 
  <pre>outer.addEventListener('touchend', <span style="color:#0000ff;">function</span><span style="color:#000000;">(){
                </span><span style="color:#008000;">//--</span><span style="color:#008000;">滑动超过 1/3才可以切换图片,否则即为无效,则吸附回去</span>
                <span style="color:#008000;">//</span><span style="color:#008000;">math.abs取绝对值</span>
                    <span style="color:#0000ff;">if</span>(isMove &amp;&amp; Math.abs(distanceX) &gt; width/3){
                        <span style="color:#0000ff;">if</span>(distanceX &gt; 0 &amp;&amp; index != 0){  <span style="color:#008000;">//</span><span style="color:#008000;">上一张</span>
                            index = index - 1<span style="color:#000000;">;
                        }
                        </span><span style="color:#0000ff;">else</span> <span style="color:#0000ff;">if</span>(distanceX &lt; 0 &amp;&amp; index != imgArr.length - 2){   <span style="color:#008000;">//</span><span style="color:#008000;">下一张</span>
                            index = index + 1<span style="color:#000000;">;
                        }
                        move(imgList , </span>"left" , -width*index, 20 , <span style="color:#0000ff;">function</span><span style="color:#000000;">(){});
                    }
                    </span><span style="color:#0000ff;">else</span> <span style="color:#0000ff;">if</span>(isMove &amp;&amp; Math.abs(distanceX) &lt; width/3){
                        move(imgList , "left" , -width*index, 20 , <span style="color:#0000ff;">function</span><span style="color:#000000;">(){});
                    }
                    setRed();
                    autoChange();
                });</span></pre> 
 </div> 

最后整理之后的代码就是这样:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		
		<style type="text/css">
			*{
				margin: 0;
				padding: 0;
			}
			#outer{
				width: 500px;
				height: 333px;
				margin: 50px auto;
				position: relative;
				overflow: hidden;
			}
			#imgList{
				list-style: none;
				position: absolute;
				left: 0px;
			}
			#imgList>li{
				float: left;
			}
			#imgList>li>img{
				width: 500px;
				height: 333px;
			}
			#navContainer{
				position: absolute;
				bottom: 15px;
			}
			
			#navContainer>a{
				z-index: 5;
				float: left;
				width: 15px;
				height: 15px;
				background-color: red;
				margin: 0 5px;
				opacity: 0.5;
				filter: alpha(opacity=50);
				border-radius: 100%;
			}
			#navContainer>a:hover{
				background-color: black;
			}
			#picLbtn, #picRbtn{
				position: absolute;
			}
			#picLbtn{
				left: 8px;
			}
			#picRbtn{
				right: 8px;
			}
		</style>
		<script type="text/javascript">
			window.onload = function(){
				var imgList = document.getElementById("imgList");
				var navContainer = document.getElementById("navContainer");
				var outer = document.getElementById("outer");
				var picLbtn = document.getElementById("picLbtn");
				var picRbtn = document.getElementById("picRbtn");
				var imgArr = document.querySelectorAll("#imgList>li>img");
				/*设置按钮居中*/
				navContainer.style.left = (outer.offsetWidth - navContainer.offsetWidth)/2 + "px";
				var tempBtnTop = (outer.offsetHeight - picLbtn.offsetHeight)/2 + "px";
				picLbtn.style.top = tempBtnTop;
				picRbtn.style.top = tempBtnTop;
				//-- 获取元素样式,最低兼容ie8
				function getStyle(obj, name) {
					if(window.getComputedStyle) {
						return getComputedStyle(obj, null)[name];
					} else {
						return obj.currentStyle[name];
					}
				}
				//-- 获取outer的宽度
				var getOuterWidth = getStyle(outer,"width");
				var widthObject = getOuterWidth.match(/\d*/);
				var width = widthObject[0];
				//-- 根据图片的数量设置ul的总宽度
				imgList.style.width = width*imgArr.length+"px";
				function move(obj, attr, target, speed, callback){
					clearInterval(obj.timer);
					var current = parseInt(getStyle(obj, attr));
					if(current > target) {
						speed = -speed;
					}
					obj.timer = setInterval(function(){
						var oldValue = parseInt(getStyle(obj, attr));
						var newValue = oldValue + speed;
						if((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) {
							newValue = target;
						}
						obj.style[attr] = newValue + "px";
						if(newValue == target) {
							clearInterval(obj.timer);
							callback && callback();
						}
					}, 30);
				}
				//设置默认选中的效果
				var index = 0;
				var allA = document.querySelectorAll("#navContainer>a");
				allA[index].style.backgroundColor = "black";
				//-- 正常开启自动切换函数
				autoChange();
				function setA(){
					if(index >= imgArr.length - 1){
						index = 0;
						imgList.style.left = 0;
					}
				}
				function setRed(){
					for(var i=0 ; i<allA.length ; i++){
						allA[i].style.backgroundColor = "";
					}
					allA[index].style.backgroundColor = "black";
				}
				var timer;
				//--自动切换图片
				function autoChange(){
					timer = setInterval(function(){
						index++;
						index %= imgArr.length;
						move(imgList , "left" , -width*index , 20 , function(){
							setA();
							setRed();
						});
					},3000);
				}
				//--实现点击导航点切换图片
				//--调用setA、move、autochange函数
				for(var i=0; i<allA.length ; i++){
					allA[i].num = i;
					allA[i].onclick = function(){
						clearInterval(timer);
						index = this.num;
						setRed();
						move(imgList , "left" , -width*index , 20 , function(){
							autoChange();
						});
					}
				picLbtn.onclick = function(){
					clearInterval(timer);
					if (index != 0){
						index = index-1;
					}
					setRed();
					move(imgList , "left" , -width*index , 20 , function(){
						autoChange();
					});
				}
				picRbtn.onclick = function(){
					clearInterval(timer);
						if (index != allA.length - 1) {
							index = index+1;
						}
						setRed();
						move(imgList , "left" , -width*index , 20 , function(){
							autoChange();
						});
					}
				}
				var startX = 0;
				var moveX = 0;
				var distanceX = 0;
				var isMove = false;
				outer.addEventListener('touchstart', function(e){
        			clearInterval(timer); //--清除定时器,要记得事件结束之后再打开
        			startX = e.touches[0].clientX;  //--触摸点的横坐标
   				});
				outer.addEventListener('touchmove',function(e){
	        		moveX = e.touches[0].clientX;//--获取当前手的横坐标
	        		distanceX = moveX - startX; //--移动的距离=现在-初始
	        		isMove = true;//证明滑动过
					move(imgList , "left" , -width*index+distanceX , 20 , function(){});
	    		});
				outer.addEventListener('touchend', function(){
	        		if(isMove && Math.abs(distanceX) > width/3){
	            		if(distanceX > 0 && index != 0){
	                		index = index - 1;
	        			}
	        			else if(distanceX < 0 && index != imgArr.length - 2){
	            			index = index + 1;
	        			}
	        			move(imgList , "left" , -width*index, 20 , function(){});
	        		}
	        		else if(isMove && Math.abs(distanceX) < width/3){
	        			move(imgList , "left" , -width*index, 20 , function(){});
	        		}
	        		setRed();
	        		autoChange();
	    		});
			}
		</script>
	</head>
	<body>
		<div id="outer">
			<ul id="imgList">
				<li><img src="img/pic/1.jpg"/></li>
				<li><img src="img/pic/2.jpg"/></li>
				<li><img src="img/pic/3.jpg"/></li>
				<li><img src="img/pic/4.jpg"/></li>
				<li><img src="img/pic/5.jpg"/></li>
				<li><img src="img/pic/1.jpg"/></li>
			</ul>
			<div id="navContainer">
				<a href="javascript:;"></a>
				<a href="javascript:;"></a>
				<a href="javascript:;"></a>
				<a href="javascript:;"></a>
				<a href="javascript:;"></a>
			</div>
			<a href="javascript:;" id="picLbtn"><img src="img/pic/picLbtn.png"></a>
			<a href="javascript:;" id="picRbtn"><img src="img/pic/picRbtn.png"></a>
		</div>
	</body>
</html>

缺点和解决(这个一定要看!!!):

缺点:切换到手机端的时候:点击导航点和左右切换按钮会出现问题

原因:这个是因为系统把点击导航点和按钮也当成了滑动事件,这样就要同时相应两组事件,所以会出问题(俺是这么理解的,对不对也不知道)

解决:解决就很简单了,反正手机端也不需要点击导航点和切换按钮(没有人会在手机上用那玩意)

   所以如果是用在响应式布局的话,判断一下屏幕宽度,小于660px:左右按钮display:none,然后把导航点事件移除,大于660px就什么都不做

   如果用在纯手机端,就直接把导航点的事件和左右按钮代码删掉就行了

   这个程序写的还是有点模块化思想的,四五六步的内容随便删掉哪个其他互不影响。

结尾:

最后奉上B站视频教程的链接https://www.bilibili.com/video/av34087791,上文的大部分内容都来自这组视频~

转载于:https://www.cnblogs.com/iszhangk/p/10923650.html

[转载于](https://blog.csdn.net/weixin_30733003/article/details/98087463)
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值