MetInfo米拓网站开发首页轮播图制作

移动web轮播图
参考实例,可以从中保存轮播图的图片,这里我们放入uploads的文件夹下,将八张图片一次改为l1.jpg,l2.jpg…

https://m.jd.com/

HTML
这里要放入十张图片,因为手指滑动的时候要从第一张滑动到最后一张,是无缝滑动,当然可以用原生的JS进行添加
最终我们可以通过移动ul来达到轮播的效果,所以ul的宽度要刚好放得下十张图片
ol下的li是分页器,也就是我们看到的圆圈,类.current为选中状态
clearfix类是清除浮动
<div class="jd_banner">
        <ul class="jd_wrap clearfix">
                <li><a href="javascript:;"><img src="uploads/l8.jpg" alt=""></a></li>
                <li><a href="javascript:;"><img src="uploads/l1.jpg" alt=""></a></li>
                <li><a href="javascript:;"><img src="uploads/l2.jpg" alt=""></a></li>
                <li><a href="javascript:;"><img src="uploads/l3.jpg" alt=""></a></li>
                <li><a href="javascript:;"><img src="uploads/l4.jpg" alt=""></a></li>
                <li><a href="javascript:;"><img src="uploads/l5.jpg" alt=""></a></li>
                <li><a href="javascript:;"><img src="uploads/l6.jpg" alt=""></a></li>
                <li><a href="javascript:;"><img src="uploads/l7.jpg" alt=""></a></li>
                <li><a href="javascript:;"><img src="uploads/l8.jpg" alt=""></a></li>
                <li><a href="javascript:;"><img src="uploads/l1.jpg" alt=""></a></li>
        </ul>
        <ol>
            <li class="current"></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ol>
    </div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
css样式
.clearfix::before,
.clearfix::after{
    content: "";
    display: block;
    height: 0;
    line-height: 0px;
    clear: both;
    visibility: hidden;
}

.jd_banner {
  max-width: 640px;
  min-width: 320px;
  margin: 100px auto;
  width: 100%;
  position: relative;
  overflow: hidden;
}
.jd_banner .jd_wrap {
  width: 1000%;
  transform: translateX(-10%);
}
.jd_banner .jd_wrap li {
  width: 10%;
  float: left;
}
.jd_banner .jd_wrap li img {
  width: 100%;
}
.jd_banner ol {
  height: 10px;
  position: absolute;
  left: 50%;
  bottom: 3px;
  transform: translateX(-50%);
}
.jd_banner ol li {
  width: 6px;
  height: 6px;
  float: left;
  border: 1px solid #fff;
  margin-left: 10px;
  border-radius: 50%;
}
.jd_banner ol li.current {
  background: #fff;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47


JS
我们主要通过控制index,translateX,监听过渡动画的结束(webkitTransitionEnd)来实现轮播
对index进行限制
相同的代码进行封装
优化代码
var jdCon = document.querySelector('.jd_banner')
    var ul = document.querySelector('.jd_banner>.jd_wrap')
    var index = 1
    var li = ul.querySelectorAll('li')
    var olLi = document.querySelectorAll('ol>li')
    var imgWidth = li[0].offsetWidth
    // 过渡移动的效果
    var transit = function(move){
        var move = move || 0
        ul.style.transition = 'all 0.5s linear'
        ul.style.transform = `translateX(${-imgWidth*index+move}px)`
    }
    // 瞬间定位效果
    var moment = function(distanceMove){
        var distanceMove = distanceMove || 0
        ul.style.transform = `translateX(${-imgWidth*index+distanceMove}px)`
        ul.style.transition = 'none'
    }
    window.onresize = function(){
        imgWidth = li[0].offsetWidth
    }
    var timer1 = setInterval(function(){
        index++;
        transit()
    }, 1000)
    ul.addEventListener('webkitTransitionEnd', function(){
        if(index>li.length-2){
            index = 1
            moment()
        }
        if(index<1){
            index = li.length-2
            moment()
        }
        document.querySelector('.current').classList.remove('current')
        olLi[index-1].classList.add('current')
    })
    var distanceStart = 0;
    var move = 0;
    var distanceEnd = 0;
    jdCon.addEventListener('touchstart',function(e){
        clearInterval(timer1)
        distanceStart = e.touches[0].clientX
    })
    jdCon.addEventListener('touchmove',function(e){
        var distance = e.touches[0].clientX
        move = distance - distanceStart
        moment(move)
    })
    jdCon.addEventListener('touchend',function(){
        if(move>imgWidth/2){
            index--
            transit()
        }else if(move<-imgWidth/2){
            index++
            transit()
        }else{
            transit()
        }
        distanceStart = 0;
        move = 0;
        distanceEnd = 0;
        timer1 = setInterval(function(){
            index++;
            transit()
        }, 1000)
    })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
整体思路
首先做好布局,ul的子元素li要在一行上,无缝链接
利用css,ul的宽度为1000%, 设置transform: translateX(-10%);,使得不会显示展示给用户的最后一张图片,显示第一张图片
自动播放轮播图
利用定时器,让index每次加1,然后过渡滚动一张图片
var timer1 = setInterval(function(){
        index++;
        ul.style.transition = 'all 0.5s linear'
        ul.style.transform = `translateX(${-imgWidth*index}px)`
    }, 1000)
1
2
3
4
5
监听webkitTransitionEnd,过渡动画结束时,清除当前的类.current,给ol下的li[index]添加一个类
过渡动画结束后,如果index过大,我们要对其进行限制,当index为9,此时界面显示的是第十张图片,也就是用户看到的第一张图片,所以我们瞬间(在0s)让其移动到第一张,在令index=1
ul.addEventListener('webkitTransitionEnd', function(){
        // 当时间过渡结束
        // 添加.current
        if(index>8){
            // 当第一张移动完成后
            // 瞬间让index变为1
            ul.style.transform = `translateX(${-imgWidth}px)`
            ul.style.transition = 'none'
            index = 1
        }        document.querySelector('.current').classList.remove('current')
        olLi[index-1].classList.add('current')
    })
1
2
3
4
5
6
7
8
9
10
11
12
ul跟随着手指的滑动而滑动,当手指滑动多少,ul跟着滑动多少
var distanceStart = 0;
    var move = 0;
    var distanceEnd = 0;
jdCon.addEventListener('touchstart',function(e){
        clearInterval(timer1)
        distanceStart = e.touches[0].clientX
    })
    jdCon.addEventListener('touchmove',function(e){
        var distance = e.touches[0].clientX
        move = distance - distanceStart
        ul.style.transform = `translateX(${-imgWidth*index+move}px)`
        ul.style.transition = 'none'
    })
1
2
3
4
5
6
7
8
9
10
11
12
13
滑动结束时做吸附效果
向右滑动时,如果滑动大于图片二分之一的宽度,当手指放开则加上过渡动画效果移动到上一张图片,此时我们移动始终是控制index
if(move>imgWidth/2){
            index--
            ul.style.transition = 'all 0.5s linear'
            ul.style.transform = `translateX(${-imgWidth*index}px)`
        }
1
2
3
4
5
向左滑动时,如果滑动大于图片二分之一的宽度,当手指放开则加上过渡动画效果移动到下一张图片,此时我们移动始终是控制index
else if(move<-imgWidth/2){
            index++
            ul.style.transition = 'all 0.5s linear'
            ul.style.transform = `translateX(${-imgWidth*index}px)`
        }
1
2
3
4
5
其它情况保持显示现状的图片
else{
            ul.style.transition = 'all 0.5s linear'
            ul.style.transform = `translateX(${-imgWidth*index}px)`
        }
1
2
3
4
最后所有的清0,开启定时器
相同代码封装,测试是否有bug,发现右滑有问题--------始终通过控制index来实现移动和切换ol分页器,要对index进行限制。对数字通过ul下的li.length来控制,将代码封装成可调用,可读性,逻辑性的代码
if(index<1){
            ul.style.transform = `translateX(${-imgWidth*8}px)`
            ul.style.transition = 'none'
            index = 8
        }
1
2
3
4
5
步骤
/*
    获取 必须知道的 变量

    步骤1: 不考虑过渡效果 直接 刷刷刷的 切换
        定时器中 index++
                判断是否越界
               修改 轮播图ul的 位置
               考虑到 索引从1开始
               css 默认 让ul 往左边窜一个屏幕宽度

    步骤2:      下方的 索引li标签 修改 外观
        由于我们是使用.current 标示当前的索引值
        清空所有li的 class
        为当前的那个 li 添加current

    步骤3:然切换有动画效果
        使用css3中的transition
        .style.transition ='all .3s';
        在获取的时候 进行添加即可

    步骤4:当我切换到 最后一张时 瞬间 切到 第一张
        关闭过度
        瞬间切换到第一张

    步骤5:对代码 进行重构 添加进来了 过渡结束知识点
        由于 我们在修改 ul的位置时 会使用过度
        当注册了 过渡结束事件之后,每次 过渡完毕 都会 调用该事件
            将 判断 index  是否 越界 以及 修改 索引的 代码 全部 迁移到 过渡结束事件中

            定时器逻辑
                index++;

                修改 ul的 位置 ->开始过渡

            过渡结束事件逻辑
                判断 index是否有效
                    进行修正
                修改索引li标签的 显示

    步骤6: 使用touch事件,实现 手指 拨动 ul滑动 效果
        touchstart
            记录开始值
            关闭定时器
            关闭过渡效果
        touchmove
            计算移动值
            修改ul的位置(在原始值的基础上进行修改,没有过渡效果的)
        touchend
            记录移动的距离(?)
            开启定时器(*)


宽高必须考虑到移动web的适配方案
可能大家会把ul进行定位,ul定位(absolute),我们就无法把父盒子撑开,也就是父盒子jd_banner就没有高度,到时ol也很难定位,影响页面布局等问题
直接给父盒子设置高度,但是我们这个高度不好设置,因为不同的屏幕图片高度是不一致的
使用translateX来移动逻辑会更简单些
注意要样式重置,比如img要去掉基线
clearfix可以不加,因为父盒子jd_banner已经设置overflow: hidden;会触发bfc
实际开发中最好使用zetop.js或则swiper.js来提高我们的开发效率
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章