功能描述:

自动无缝轮播图片,底部小圆点跟图片保持一致;手指左右移动轮播图,移动距离大于50px播放下一张(或上一张),小于50px则回弹

具体功能实现:

1.定时器 自动轮播图片

先声明一个index=0用来存图片索引;

添加一个定时器,每隔两秒调用一次,每调用一次定时器(图片播放一次)index就加一;

通过transform(变形)属性和transition(过渡)属性实现图片的轮播。

 var index = 0;
var timer = setInterval(function() {
index++;
var translatex = -index * w; // ul要移动的距离
ul.style.transition = 'all .4s';
ul.style.transform = 'translateX(' + translatex + 'px)';
}, 2000);

2.实现无缝轮播并让小圆点和图片一致

给ul绑定监听函数(每次轮播移动的都是整个ul),过渡结束(transitionend)时执行;

判断索引index是否大于等于3,是的话说明已经播放到最后一张,让index=0并去掉过渡效果,快速回到第一张;

判断索引是否小于0,小于0说明用户一开始是往前滑的,让index=2并去掉过渡效果,快速到最后一张;

让底部小圆点跟着一起动(给当前li添加类,把其他的li删除类)

 ul.addEventListener('transitionend', function() {
if(index >= 3) {
index = 0;
ul.style.transition = ''; // 去掉过渡效果
var translatex = -index * w;
ul.style.transform = 'translateX(' + translatex + 'px)';
} else if(index < 0) {
index = 2;
ul.style.transition = '';
var translatex = -index * w;
ul.style.transform = 'translateX(' + translatex + 'px)';
}
// 让底部小圆点跟着一起动
// 将带有current类的li去掉该类
ol.querySelector('.current').classList.remove('current');
// 给当前li添加current类
ol.children[index].classList.add('current');
})

3.实现图片跟随手指移动先声明几个变量用来存储手指初始位置、手指是否在屏幕上移动以及手指移动的距离

var startX = 0;    // 手指初始位置
var moveX = 0; // 手指在屏幕上移动的距离
var flag = false; // 记录用户是否移动了手指

给ul绑定手指触摸事件,记录手指触摸的初始位置,并清除定时器(不让它自动轮播了)

 ul.addEventListener('touchstart', function(e) {
startX = e.targetTouches[0].pageX; // 手指的初始触摸位置(左右轮播,只记录x就可以了)
clearInterval(timer);
})

给ul绑定手指移动事件

 ul.addEventListener('touchmove', function(e) {
moveX = e.targetTouches[0].pageX - startX; // 手指移动的距离
var translatex = -index * w + moveX;
ul.style.transition = 'none';
ul.style.transform = 'translateX(' + translatex + 'px)';
flag = true; // 手指移动了,将flag改为true
e.preventDefault(); // 阻止屏幕滚动的默认行为(防止用户移动轮播图的时候屏幕也跟着上下滚动)
})

4.实现手指离开后图片的轨迹看用户是否移动了图片,flag为true才去判断:

①手指移动距离大于50px图片播放上一张或下一张②手指移动距离小于50px图片回弹;

结束后把flag改为false,并重新开启定时器让它继续自动轮播

 ul.addEventListener('touchend', function(e) {
if(flag) { // flag==true(移动图片)时才去判断用户的移动方向和距离
if(Math.abs(moveX) > 50) { // 移动距离大于50时 滑向上一张或下一张(moveX可能为正也可能为负,Math.abs()取绝对值)
if(moveX > 0) { // 大于0右滑 图片索引减一
index--;
} else { // 小于0左滑 图片索引加一
index++;
}
var translatex = -index * w;
ul.style.transition = 'all .3s';
ul.style.transform = 'translateX(' + translatex + 'px)';
} else { // 小于50px就回弹
var translatex = -index * w;
ul.style.transition = 'all .1s';
ul.style.transform = 'translateX(' + translatex + 'px)';
}
}
// 结束后 把flag重新改为false,并开启定时器让图片开始轮播
flag = false;
// 先清除再开启,保证只有一个定时器在运行(不然会有bug)
clearInterval(timer);
timer = setInterval(function() {
index++;
var translatex = -index * w;
ul.style.transition = 'all .4s';
ul.style.transform = 'translateX(' + translatex + 'px)';
}, 2000);
})

注:功能还可以继续优化,比如动态添加图片,动态添加底部小圆点等。具体实现方法可以参照我上一篇 JavaScript实现动态轮播图效果 。

具体实现代码如下:

HTML代码:

 <div class="focus">
<ul>
<!-- 用户可能一开始往上一张滑,所以要多添加一个focus3 -->
<li><img src="data:images/focus3.jpg" alt=""></li>
<li><img src="data:images/focus1.jpg" alt=""></li>
<li><img src="data:images/focus2.jpg" alt=""></li>
<li><img src="data:images/focus3.jpg" alt=""></li>
<li><img src="data:images/focus1.jpg" alt=""></li>
</ul>
<ol>
<li class="current"></li>
<li></li>
<li></li>
</ol>
</div>

CSS代码:

 * {
margin:;
padding:;
}
body {
margin: 0 auto;
max-width: 540px;
min-width: 320px;
background: #f6f6f6;
}
.focus {
width: 100%;
position: relative;
margin-top: 50px;
overflow: hidden;
}
.focus ul {
width: 500%;
overflow: hidden;
margin-left: -100%;
}
.focus ul li {
float: left;
width: 20%;
}
.focus ul img {
width: 100%;
}
.focus ol {
position: absolute;
bottom: 5px;
right: 5px; }
.focus ol li {
width: 5px;
height: 5px;
display: inline-block;
background-color: #fff;
border-radius: 4px;
transition: all .2s;
}
.focus .current {
width: 15px;
}

JavaScript代码:

 window.addEventListener('load', function() {
var focus = document.querySelector('.focus');
var ul = focus.children[0]; // 获取focus的第一个孩子,也就是ul
var ol = focus.children[1];
var w = focus.offsetWidth; // 获取focus的宽度
var index = 0; // 用来记录图片索引
var timer = setInterval(function() { // 添加定时器,两秒调用一次
index++; // 每调用一次(轮播一次),图片索引号+1
var translatex = -index * w; // ul要移动的距离
ul.style.transition = 'all .4s'; // 添加过渡属性(css3里的属性)
ul.style.transform = 'translateX(' + translatex + 'px)';
}, 2000);
// 给ul绑定监听函数(每次轮播移动的都是整个ul) 过渡结束(transitionend)时执行
ul.addEventListener('transitionend', function() {
if(index >= 3) { // 索引 > 3说明已经轮播到最后一张了
index = 0;
// 去掉过渡效果 快速回到第一张
ul.style.transition = '';
var translatex = -index * w;
ul.style.transform = 'translateX(' + translatex + 'px)';
} else if(index < 0) { // 索引 < 0说明用户一开始是往前滑的
index = 2;
ul.style.transition = '';
var translatex = -index * w;
ul.style.transform = 'translateX(' + translatex + 'px)';
}
// 让底部小圆点跟着一起动
// 将带有current类的li去掉该类
ol.querySelector('.current').classList.remove('current');
// 给当前li添加current类
ol.children[index].classList.add('current');
})
// 手指滑动轮播图
var startX = 0; // 用来存储手指初始位置
var moveX = 0; // 用来存储手指在屏幕上移动的距离
var flag = false; // 记录用户是否在图上移动了手指
// 给ul绑定手指触摸事件
ul.addEventListener('touchstart', function(e) {
startX = e.targetTouches[0].pageX; // 手指的初始触摸位置(左右轮播,只记录x就可以了)
clearInterval(timer); // 当手指触摸屏幕时清除定时器(不让它自动轮播了)
})
// 给ul绑定手指移动事件
ul.addEventListener('touchmove', function(e) {
moveX = e.targetTouches[0].pageX - startX; // 手指移动的距离
var translatex = -index * w + moveX;
ul.style.transition = 'none';
ul.style.transform = 'translateX(' + translatex + 'px)';
flag = true; // 手指移动了,将flag改为true
e.preventDefault(); // 阻止屏幕滚动的默认行为
})
// 给ul绑定手指离开事件
ul.addEventListener('touchend', function(e) {
if(flag) { // flag==true(移动图片)时才去判断用户的移动方向和距离
if(Math.abs(moveX) > 50) { // 移动距离大于50时 滑向上一张或下一张(moveX可能为正也可能为负,Math.abs()取绝对值)
if(moveX > 0) { // 大于0右滑 图片索引减一
index--;
} else { // 小于0左滑 图片索引加一
index++;
}
var translatex = -index * w;
ul.style.transition = 'all .3s';
ul.style.transform = 'translateX(' + translatex + 'px)';
} else { // 小于50px就回弹
var translatex = -index * w;
ul.style.transition = 'all .1s';
ul.style.transform = 'translateX(' + translatex + 'px)';
}
}
// 结束后 把flag重新改为false,并开启定时器让图片开始轮播
flag = false;
// 先清除再开启,保证只有一个定时器在运行(不然会有bug)
clearInterval(timer);
timer = setInterval(function() {
index++;
var translatex = -index * w;
ul.style.transition = 'all .4s';
ul.style.transform = 'translateX(' + translatex + 'px)';
}, 2000);
})
})

原生JS实现移动端轮播图的更多相关文章

  1. 原生JS面向对象思想封装轮播图组件

    原生JS面向对象思想封装轮播图组件 在前端页面开发过程中,页面中的轮播图特效很常见,因此我就想封装一个自己的原生JS的轮播图组件.有了这个需求就开始着手准备了,代码当然是以简洁为目标,轮播图的各个功能 ...

  2. 原生js写一个无缝轮播图插件(支持vue)

    轮播图插件(Broadcast.js) 前言:写这个插件的原因 前段时间准备用vue加上网易云的nodejs接口,模拟网易云音乐移动端.因为想自己写一遍所有的代码以及加固自己的flex布局,所以没有使 ...

  3. 原生js实现响应式轮播图,支持电脑端点击切图,手机端滑动切图

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

  4. 原生js的懒人轮播图

    <style> body{ margin: 0; padding: 0px;}#carousel{ margin: auto; /* 居中 */ width: 600px; /* 设置宽度 ...

  5. 原生js实现简单移动端轮播图

    最近项目不是很忙,自己就用原生js写了一个简单的移动端轮播图的小demo,可实现自动轮播和手势滑动轮播,然后就把它记录到个人博客里.还有很多不足的地方,希望多多指出,以便改进. 1.代码部分 分为四个 ...

  6. 告别组件之教你使用原生js和css写移动端轮播图

    在工作中由于项目需要要写一个轮播图,本想使用组件直接调用实现快速开发,但是一想到自己经常使用组件但是让自己手写的话确实一点都不会. 一个不会手写组件的前端程序员不是一个好程序员!于是打算自己手写一个. ...

  7. 移动端轮播图实现方法(dGun.js)

    本文章介绍在移动端无缝隙轮播图实现的原理,这个轮子比较简单,但可以方便刚刚入门的同学参考.最终效果是在移动端无缝隙无限滑动,可以自定义轮播的速度.支持手势左右滑动.最后会放上源码. HTML部分 &l ...

  8. 移动端轮播图vue-awesome-swiper

    日常写设计文档,日常写Demo,写轮播图的时候觉得bootstrap不适合移动端,或者说不是轻量级的,于是换成Swiper,但是写的时候才发现怎么把这东西嵌到Vue里面啊? Σ( ° △ °|||)︴ ...

  9. 用html +js+css 实现页面轮播图效果

    html 页面 <html lang="en"> <head> <meta charset="UTF-8"> <met ...

随机推荐

  1. JavaScript笔记九

    1.数组方法 reverse() - 可以用来反转一个数组,它会对原数组产生影响 concat() - 可以连接两个或多个数组,它不会影响原数组,而是新数组作为返回值返回 join() - 可以将一个 ...

  2. ORA-00845 startup启动不起来关于磁盘空间扩充

    问题描述:今天在虚拟机下进行startup的操作,但是没有起来,系统报错:ORA-00845: MEMORY_TARGET not supported on this system 1.startup ...

  3. Selenium+Java(六)Selenium 强制等待、显式等待、隐实等待

    前言 在实际测试过程中,由于网速或性能方面的原因,打开相应的网页后或在网页上做了相应的操作,网页上的元素可能不会马上加载出来,这个时候需要在定位元素前等待一下,等元素加载出来后再进行定位,根据实际使用 ...

  4. Fragment源码分析

    转载请标明出处:http://blog.csdn.net/shensky711/article/details/53171248 本文出自: [HansChen的博客] 概述 Fragment表示 A ...

  5. 【10分钟学Spring】:@Profile、@Conditional实现条件化装配

    根据不同的环境来装配不同的bean 企业级开发中,我们一般有多种环境,比如开发环境.测试环境.UAT环境和生产环境.而系统中有些配置是和环境强相关的,比如数据库相关的配置,与其他外部系统的集成等. 如 ...

  6. netty的调优-及-献上写过注释的源码工程

    Netty能干什么? Http服务器 使用Netty可以编写一个 Http服务器, 就像tomcat那样,能接受用户发送的http请求, , 只不过没有实现Servelt规范, 但是它也能解析携带的参 ...

  7. 为什么现在使用多周期CPU,而单周期CPU被弃用?

    最初设计的CPU结构简单,内部不复杂.之所以制造它是为了让机器自动跑程序,算数. 早期CPU都是单周期的,人们没考虑那么多,性能啥的.就让CPU每个时钟周期跑一个指令,这些时钟周期等长.这样下来,有的 ...

  8. 充满含金量的一场云原生Meetup,入场券免费发送中……

    在武汉,你离这场云原生盛会,只有一步之遥 华为云.百度.斗鱼.海云基因,五位重量级专家 K8s调度.深度学习平台.斗鱼实战.基因大数据-五个干货议题 日,与您相约Cloud Native Days C ...

  9. 在华为云ECS上手工通过Docker部署tomcat

    本文介绍了如何在华为云上ECS上手工通过Docker部署tomcat,并提供了Docker常用操作 一.环境准备 ECS:操作系统版本:    CentOS Linux release 7.6.181 ...

  10. Python装饰器总结,带你几步跨越此坑!

    欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),输入关键字"加群",加入华为云线上技术讨论群:输入关键字"最新活动",获取华 ...