1.触屏事件
1.1触屏事件概述
移动端浏览器兼容性好,我们不需要考虑以前JS的兼容问题,可以放心使用原生JS书写效果,但是移动端也有自己独特的地方,比如触屏事件touch(也叫触摸事件),Android和IOS都有。
touch对象代表一个触摸点,触摸点可能是一根手指,也可能是一根笔。触屏事件可以相应用户手指对屏幕或者触控板操作
常见的触屏事件:
- 1.
touchstart
:手指触摸到一个DOM元素时触发 - 2.
touchmove
:手指在一个DOM元素上滑动时触发 - 3.
touchend
:手指从一个DOM元素上移开时触发
1.2触摸事件对象(TochEvent)
TouchEvent是一类描述手指在触摸平面(触摸屏、触摸板等)的状态变化的事件。这类事件用于描述一个或者多个触点,使开发者可以检测触点的移动,触点的增加和减少,等等
touchstart、touchmove、touchend三个时间都会各自有事件对象
触摸事件对象终点我们看三个常见对象列表
- 1.
touches
:正在触摸屏幕的所有手指的一个列表 - 2.
targetTouches
:正在触摸当前DOM元素上的手指的一个列表(最常使用) - 3.
changeTouches
:手指状态发生了改变的列表,从无到有,从有到无变化
1.3移动端拖动元素
1.touchstart、touchmove、touchend可以实现拖动元素
2.但是拖动元素需要当前手指的坐标值,我们可以使用targetTouches[0]
里面的pageX
和pageY
3.移动端拖动的原理:手指移动中,计算出手指移动的距离。然后用盒子原来的位置 手指移动的距离
4.手指移动的距离:手指滑动中的位置减去手指刚开始触摸的位置
拖动元素三部曲:
(1)触摸元素touchstart:获取手指初始坐标,同时获得盒子原来的位置
(2)移动手指touchmove:计算手指的滑动距离,并且移动盒子
(3)离开手指touchend
注意:手指移动也会触发滚动屏幕所以这里要阻止默认的屏幕滚动e.preventDefault()
;
2.移动轮播案例
三张图片进行轮播,需要将第一张克隆一张到最后,最后一张克隆一张到第一张,大概意思为下图:
html布局
代码语言:javascript复制<div class="container">
<div class="banner clearfix">
<ul class="clearfix">
<li><a href="#"><img src="images/ban3.jpg" alt=""></a></li>
<li><a href="#"><img src="images/ban1.jpg" alt=""></a></li>
<li><a href="#"><img src="images/ban2.jpg" alt=""></a></li>
<li><a href="#"><img src="images/ban3.jpg" alt=""></a></li>
<li><a href="#"><img src="images/ban1.jpg" alt=""></a></li>
</ul>
<!-- 小圆点 -->
<ol>
<li class="current"></li>
<li></li>
<li></li>
</ol>
</div>
</div>
css样式
代码语言:css复制 * {
margin: 0px;
padding: 0px;
/* 移动端适配核心点
1.不允许网页出现横向滚动条
2.页面盛满屏幕,盒子宽度与屏幕一致 100%
3.让盒子的内容宽高width/height包含padding与border,避免出现横向滚动条
*/
box-sizing: border-box;
}
body {
/* 移动端默认字体一般是12px */
font-size: 12px;
}
li {
list-style: none;
}
img {
vertical-align: middle;
/* 图片居中 */
}
a {
color: #000;
/* 取消a标签默认下划线 */
text-decoration: none;
/* 移动端点击a链接出现蓝色背景问题解决 */
-webkit-tap-highlight-color: transparent;
}
/* 清除浮动,解决margin-top塌陷 */
.clearfix:after {
content: "";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.container {
width: 100%;
/* 限制版心的宽度范围,在pc端也能显示移动端网页 */
max-width: 1024px;
min-width: 320px;
margin: 0 auto;
}
.banner {
width: 100%;
margin-top: 44px;
position: relative;
overflow: hidden;
}
.banner img {
width: 100%;
}
.banner ol {
position: absolute;
right: 20px;
bottom: 5px;
}
.banner ol .current {
width: 15px;
}
.banner ol li {
display: inline-block;
width: 5px;
height: 5px;
border-radius: 2px;
list-style: none;
background-color: red;
}
.banner ul {
width: 500%;
margin-left: -100%;
overflow: hidden;
}
.banner ul li {
float: left;
width: 20%;
}
案例分析:
- 1.自动轮播
- 2.开启定时器
- 3.移动端移动,可以使用translate移动
- 4.想要图片缓动效果,添加过渡transition效果
实现播放功能后,接着实现无缝滚动
- 自动播放功能无缝滚动
- 注意:我们判断条件是要等到图片滚动完毕再去判断,就是过渡完成后判断
- 此时需要添加检测过渡完成事件transitionend
- 判断条件:如果索引号等于3说明走到最后一张图片,此时索引号要复原为0
- 此时图片,去掉过渡效果,然后移动
- 如果索引号小于0,说明是倒着走,索引号改为2
- 此时图片,去掉过渡效果,然后移动
无缝滚动实现完之后接着实现改变li小圆点的样式变换
这里介绍一个新的classList
属性:它是HTML5新增的一个属性,返回元素的类名,但是ie10以上的版本才支持,该属性用于在元素中添加、移出、切换css类,有以下方法:
元素.classList.add('类名')、元素.classList.remove('类名')、元素.classList.toggle('类名')
代码语言:javascript复制 <style>
.bg{
background-color: black;
}
</style>
<div class="one two"></div>
<button>开关</button>
<script>
var div = document.querySelector("div");
console.log(div.classList);//DOMTokenList(2) ["one", "two", value: "one two"]
//1.添加类名 是在后面追加类名不会覆盖以前的类名
div.classList.add('three');
console.log(div.classList);//DOMTokenList(3) ["one", "two", "three", value: "one two three"]
//2.删除类名
div.classList.remove('one');
console.log(div.classList);//DOMTokenList(2) ["two", "three", value: "two three"]
//3.切换类
var btn = document.querySelector("button");
btn.onclick = function(){
document.body.classList.toggle("bg");
}
</script>
了解完classList之后我们来做小圆点样式改变效果:
- 1.小圆点跟随变化效果
- 2.吧ol中li带有current类名选出来去掉类名current
- 3.让当前索引号的li加上current
- 4.注意:等着过渡结束之后再去添加current,所以要写在transitionend中
接着开始实现手指滑动轮播:
- 1.本质就是ul跟着手指移动,简单说就是移动拖动元素
- 2.触摸元素touchstart:获取手指初始坐标
- 3.移动手指touchmove:计算手指的滑动距离,并且移动盒子
- 4.手指离开touchend,根据移动距离去判断是回弹还是播放上一张下一张
- 5.如果移动距离小于某个像素 就回弹
- 6.如果移动距离大于某个像素就上一张或者下一张
js代码:
代码语言:javascript复制<script>
//1.获取元素
var banner = document.querySelector(".banner");
var ul = document.querySelector(".banner ul");
var ol = document.querySelector(".banner ol");
//获取banner的宽度
var w = banner.offsetWidth;
//2.利用定时器自动轮播图片
var index = 0;
var timer = setInterval(function () {
index ;
var translatex = -index * w;
ul.style.transition = "all .3s";
ul.style.transform = "translateX(" translatex "px)";
}, 2000);
//等着过度完成之后,再去判断 监听过渡完成的时间transitionend
ul.addEventListener("transitionend", function () {
//无缝滚动
if (index >= 3) {
index = 0;
//为了让图片瞬间到索引0处,要取消掉过渡效果
ul.style.transition = "none";
//利用最新的索引乘宽度 滚动图片
var translatex = -index * w;
ul.style.transform = "translateX(" translatex "px)";
} else if (index < 0) { //同理
index = 2;
ul.style.transition = "none";
var translatex = -index * w;
ul.style.transform = "translateX(" translatex "px)";
}
//3.小圆点跟随变化
//吧ol中的li带有current类名选出来去掉类名 remove
ol.querySelector('.current').classList.remove('current')
//让当前索引号的小li加上current 类名
ol.children[index].classList.add('current');
});
//4.手指滑动轮播图
//触摸元素touchstart:获取手指初始坐标
var startX = 0;
var moveX = 0; //因为后面需要使用移动距离,因此定义一个全局变量
var flag = false;
ul.addEventListener("touchstart", function (e) {
//当触摸到ul时候 清除定时器
clearInterval(timer);
startX = e.targetTouches[0].pageX;
});
//移动手指 touchmove:计算手指的滑动距离 ,并且移动盒子
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;//如果用户手指移动了我们才判断否则不去判断效果
e.preventDefault();//阻止滚动屏幕的行为
});
//手指离开,根据移动距离去判断是回弹还是播放上一张下一张
ul.addEventListener("touchend", function (e) {
if (flag) {
//如果移动距离大于50像素 我们就播放上一张或者下一张
if (Math.abs(moveX) > 50) { //为了防止负数需要取绝对值
//如果是右滑 播放上一张moveX是正数
//如果是左滑 播放下一张moveX是负数
moveX > 0 ? index-- : 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)";
}
}
//手指离开就清楚定时器
clearInterval(timer);
timer = setInterval(function () {
index ;
var translatex = -index * w;
ul.style.transition = "all .3s";
ul.style.transform = "translateX(" translatex "px)";
}, 2000);
});
</script>