1. 触屏事件
1.1 触屏事件概述
移动端的动画效果能用C3写就尽量用C3写,如果非要交互,那么就用CS搭配着C3来写
<body>
<div></div>
<script>
//1. 获取元素
var div = document.querySelector('div');
div.addEventListener('touchstart', function() {
console.log('我摸了你');
});
div.addEventListener('touchmove', function() {
console.log('我在滑动');
});
div.addEventListener('touchend', function() {
console.log('我溜了');
});
</script>
</body>
1.2 触摸事件对象TouchEvent
对于触摸事件对象主要记忆一下三个属性
<body>
<div></div>
<script>
// 触摸事件对象
// 1. 获取元素
// 2. 手指触摸DOM元素事件
var div = document.querySelector('div');
div.addEventListener('touchstart', function(e) {
// console.log(e);
// (1)touches 正在触摸屏幕的所有手指的列表
// (2)targetTouches 正在触摸当前DOM元素的手指列表
// 如果侦听的是一个DOM元素,touches和targetTouches他们两个是一样的
// (3)changedTouches 手指状态发生了改变的列表 从无到有 或者 从有到无
// 因为我们一般都是触摸元素 所以最经常使用的是 targetTouches
console.log(e.targetTouches[0]);
// targetTouches[0] 就可以得到正在触摸dom元素的第一个手指的相关信息比如 手指的坐标等等
});
// 3. 手指在DOM元素身上移动事件
div.addEventListener('touchmove', function() {
});
// 4. 手指离开DOM元素事件
div.addEventListener('touchend', function(e) {
// console.log(e);
// 当我们手指离开屏幕的时候,就没有了 touches 和 targetTouches 列表
// 但是会有 changedTouches
});
</script>
</body>
1.3 移动端拖动元素
<body>
<div></div>
<script>
//(1)触摸元素 touchstart:获取手指初始坐标,同时获得盒子原来位置
//(2)移动手指 touchmove:计算手指滑动距离,并且移动盒子
//(3)离开手指 touchend:
var div = document.querySelector('div');
var startX = 0; //获取手指初始坐标
var startY = 0;
var x = 0; //获取盒子原来的位置
var y = 0;
div.addEventListener('touchstart', function(e) {
//获取手指初始坐标
startX = e.targetTouches[0].pageX; //targetTouches[0]表示第一个手指
startY = e.targetTouches[0].pageY;
x = this.offsetLeft;
y = this.offsetTop;
});
div.addEventListener('touchmove', function(e) {
//计算手指移动距离:手指移动之后的距离减去手指初始坐标
var moveX = e.targetTouches[0].pageX - startX;
var moveY = e.targetTouches[0].pageY - startY;
//移动盒子 盒子新位置=盒子原来的位置+手指移动距离
this.style.left = x + moveX + 'px';
this.style.top = y + moveY + 'px';
e.preventDefault(); //阻止屏幕滚动的默认行为
})
</script>
</body>
2. 移动端常见特效
2.1 移动端的轮播图
-在以前携程网的代码基础上进行修改。
-
无缝滚动
-
classList属性:是H5新增的一个属性,返回元素类名。但是ie10以上版本才支持
<body>
<div class="one two"></div>
<button>开关灯</button>
<script>
//1. classList返回元素的类名
var div = document.querySelector('div');
console.log(div.classList); //DOMTokenList(2) ["one", "two", value: "one two"] 以伪数组的形式返回元素所有类名
console.log(div.classList[0]); //one 返回第一个类名
//2. classList为元素缀加类名 不覆盖原来的类(className是覆盖原来的类)
div.classList.add('three'); //现在div这个元素有3个类名了。注意是three 而不是.three
//3. classList删除元素的类名
div.classList.remove('one'); //div的one类就被删除了
//4. classList切换元素类名
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
document.body.classList.toggle('bg'); //点击一下按钮就让body加上这个类,再点击一下就让body去掉这个类
})
</script>
</body>
<style>
.bg {
background-color: black;
}
</style>
具体代码
- 结构部分
<!-- 返回顶部模块 -->
<div class="goBack"></div>
<!-- 顶部搜索 -->
<div class="search-index"></div>
<!-- 焦点图模块 -->
<div class="focus">
<ul>
<li><img src="upload/focus3.jpg" alt=""></li>
<!--用于无缝滚动(考虑到移动端用户会拉图片)-->
<li><img src="upload/focus1.jpg" alt=""></li>
<li><img src="upload/focus2.jpg" alt=""></li>
<li><img src="upload/focus3.jpg" alt=""></li>
<li><img src="upload/focus1.jpg" alt=""></li>
<!--用于无缝滚动-->
</ul>
<!-- 小圆点 -->
<ol>
<li class="current"></li>
<li></li>
<li></li>
</ol>
</div>
- CSS
/* goBack */
.goBack {
display: none;
/*返回顶部的小箭头先隐藏,当页面滚动到某一部分的时候才显示*/
position: fixed;
bottom: 50px;
right: 20px;
38px;
height: 38px;
background: url(../images/back.png) no-repeat;
background-size: 38px 38px;
}
/* focus */
.focus {
position: relative;
padding-top: 44px;
overflow: hidden;
/*保证不让5个焦点图的宽ul撑大页面*/
}
.focus img {
100%;
}
.focus ul {
overflow: hidden;
/*清除浮动*/
500%;
/*让ul宽一点,否则就算每个小li添加浮动,也不会在一行显示*/
margin-left: -100%;
/*让ul往左走一个focus的宽度,这样焦点框里初始显示的才是第一张图,而不是第三张图片*/
}
.focus ul li {
float: left;
20%;
}
.focus ol {
position: absolute;
bottom: 5px;
right: 5px;
margin: 0;
}
.focus ol li {
display: inline-block;
5px;
height: 5px;
background-color: #fff;
list-style: none;
border-radius: 2px;
transition: all .3s;
/*让小圆点缓慢变化*/
}
.focus ol li.current {
15px;
}
-JS
window.addEventListener('load', function() {
//1. 获取元素
var focus = document.querySelector('.focus');
var ul = focus.children[0];
var ol = focus.children[1];
//获得focus的宽度
var w = focus.offsetWidth;
console.log(w);
//2. 利用定时器自动播放轮播图
var index = 0;
var timer = setInterval(function() {
index++;
var translatex = -index * w;
ul.style.transition = 'all .3s'; //为ul添加 过度效果,让焦点图光滑滑动
ul.style.transform = 'translateX(' + translatex + 'px)';
}, 2000);
//3. 无缝滚动
ul.addEventListener('transitionend', function() {
//transitionend:监听过度完成事件 这里是等到过度完成之后再去判断
//当从indx=2到index=3过度结束之后,index=3立马没有过度地跳到index=0
if (index >= 3) { //当图片走到最后一张的时候
ul.style.transition = 'none'; //跳回到第一张这个动作是快速跳回,不做动画
//跳回到第一张之后,重新滚动
index = 0;
var translatex = -index * w;
ul.style.transform = 'translateX(' + translatex + 'px)'; //跳回到初始位置的第一张
} else if (index < 0) {
ul.style.transition = 'none';
index = 2;
var translatex = -index * w;
}
//4. 小圆点跟随变化效果 小圆点的变化一定是写在过度结束之后,所以写在该代码块立马
//一下这种思想避免的for循环的排他思想
//把ol里带有current类名的li选出来,去掉类名 remove
ol.querySelector('li.current').classList.remove('current'); //ol.querySelector('li.current')也可以写成ol.querySelector('li.current');
//让当前索引号的小li加上current add
ol.children[index].classList.add('current');
});
//5 手指滑动轮播图
//触摸元素touchstart: 获取手指初始位置
var startX = 0;
var moveX = 0; //记录移动距离
var flag = false;
ul.addEventListener('touchstart', function(e) {
startX = e.targetTouches[0].pageX; //targetTouches[0]表示第一个手指
//用手滑动的时候不需要再自动播放轮播图
clearInterval(timer);
});
//移动手指:计算手指滑动距离,并且移动盒子
ul.addEventListener('touchmove', function(e) {
//计算移动距离
moveX = e.targetTouches[0].pageX - startX;
//移动盒子: 盒子原来的位置+手指移动的距离
//盒子原来的位置:-index*w 滚动到第几张图片就是第几张图片乘以盒子的宽度
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) { //flag=true的时候,说明用户已经移动过手指,之后我们再进行响应的计算
//(1)如果移动距离大于50像素我们就播放上一张或者下一张
if (Math.abs(moveX) > 50) {
if (moveX > 0) { //如果是右滑就是播放上一张moveX是正值
index--;
} else { //如果是左滑就是播放下一张moveX是负值
index++;
}
var translatex = -index * w;
ul.style.transition = 'all .3s';
ul.style.transform = 'translateX(' + translatex + 'px)';
} else {
//(2)如果移动距离小于50像素我们就回弹 会弹就是不让index有任何变化
var translatex = -index * w;
ul.style.transition = 'all .3s';
ul.style.transform = 'translateX(' + translatex + 'px)';
}
}
// 手指离开的时候就开启定时器
clearInterval(timer); //开定时器前先清一次
//开启定时器
timer = setInterval(function() {
index++;
var translatex = -index * w;
ul.style.transition = 'all .3s'; //为ul添加 过度效果,让焦点图光滑滑动
ul.style.transform = 'translateX(' + translatex + 'px)';
}, 2000);
});
//返回顶部制作
var goBack = document.querySelector('.goBack');
var nav = document.querySelector('nav');
window.addEventListener('scroll', function() {
if (window.pageYOffset >= nav.offsetTop) {
goBack.style.display = 'block';
} else {
goBack.style.display = 'none';
}
});
goBack.addEventListener('click', function() {
window.scroll(0, 0);
})
})
2.2 click延迟解决方案
上述函数封装一次只能为一个元素解决click延时的问题,若是有100个元素就要调用100次
第三个解决方案:就是使用fastclick插件,下文将会介绍https://github.com/ftlabs/fastclick
3. 移动端常用开发插件
3.1 什么是插件
- 进入Github官网:https://github.com/ftlabs/fastclick
- 选择lib文件夹
- 打开该文件夹下的fastclick.js文件,复制后保存到本地
3.2 fastclick.js插件的使用
- 引入fastclick.js文件
- 使用fastclick.js文件:遵循官网的使用规范(https://github.com/ftlabs/fastclick)在该网站下的Usage这一栏
- 举例:
<!-- 1.引入 -->
<script src="fastclick.js"></script>
<body>
<div></div>
<script>
//2. 使用
//利用下面这段代码,页面中的元素就都解决了click延时问题了
if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded', function() {
FastClick.attach(document.body);
}, false);
}
//下面代码中的click将不再延迟
var div = document.querySelector('div');
div.addEventListener('click', function() {
alert(11);
});
</script>
</body>
3.3 Swiper插件的使用
这是开源、免费、强大的触摸滑动插件。下面以写JD移动端的轮播图为例子(在原先的代码上修改)
中文官网地址: https//www.swiper.com.cn/
-
登陆网站-->点击导航栏的"获取Swiper"-->点击“下载Swiper”-->下载swiper-4.5.3.zip
-
解压下载的文件-->找到demos文件夹(里面全是滑动的样式案例.html)。本案例选用:030-pagination.html
-
disk文件夹下有上述案例对应的css和Js文件(ps:cs文件夹下的swiper.css和swiper.css是两个一样的文件,知识swiper.min.css是经过压缩的)。本案例选用swiper.min.css和swiper.min.js文件,将其分别放入css和js的文件夹下
-
引入插件相关文件
同时新建自己的JS文件,并引入
<!-- 引入我们的css初始化文件 -->
<link rel="stylesheet" href="css/normalize.css">
<!-- 引入我们首页的css -->
<link rel="stylesheet" href="css/index.css">
<!-- 引入swipercss文件 -->
<link rel="stylesheet" href="css/swiper.min.css">
<!-- 引入swiper js 文件 -->
<script src="js/swiper.min.js"></script>
<!-- 引入我们自己的js文件 -->
<script src="js/index.js"></script>
- 按照规定语法使用
(1)打开030-pagination.html文件
(2)查看网页源代码
(3)先复制结构,
<!-- Swiper -->
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
<div class="swiper-slide">Slide 4</div>
<div class="swiper-slide">Slide 5</div>
<div class="swiper-slide">Slide 6</div>
<div class="swiper-slide">Slide 7</div>
<div class="swiper-slide">Slide 8</div>
<div class="swiper-slide">Slide 9</div>
<div class="swiper-slide">Slide 10</div>
</div>
<!-- Add Pagination -->
<div class="swiper-pagination"></div>
</div>
(4)并将上述结构中的Slide 1,Slide 2,Slide 3...替换为相应的图片,最终的结构修改如下
<!-- 滑动图 -->
<div class="slider">
<!-- Swiper 注意不要更改里面的结构和类名 -->
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">
<img src="upload/banner.dpg" alt="">
</div>
<div class="swiper-slide">
<img src="upload/banner1.dpg" alt="">
</div>
<div class="swiper-slide">
<img src="upload/banner2.dpg" alt="">
</div>
<div class="swiper-slide">
<img src="upload/banner3.dpg" alt="">
</div>
</div>
<!-- Add Pagination -->
<!-- 这里就是小圆点 -->
<div class="swiper-pagination"></div>
</div>
</div>
(5)复制相关样式,粘贴到index.css中
.swiper-container {
100%;
height: 100%;
}
.swiper-slide {
text-align: center;
font-size: 18px;
background: #fff;
/* Center slide text vertically */
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
}
(6)复制js相关内容并复制到自己的index.js文件中
window.addEventListener('load', function() {
//复制的内容
var swiper = new Swiper('.swiper-container', {
pagination: {
el: '.swiper-pagination',
},
});
})
有其他需要可以查看该网站导航栏上的中文教程以及API文档等内容。
- 如果有JS内容需要修改,可以查看API文档里每个参数的含义
- 如何是CSS内容需要修改,可用在页面上检查元素,得到相关的类名,再去我们自己的CSS里为这个类名写一个新的样式覆盖掉原来的样式,注意添加 !important用于提高层级
综上:找到想要的样式,查看源码,从上到下往自己的文件中引入,再进行相应的修改即可。
3.4 其他移动端常见插件
- superslide: http://www.superslide2.com
- iscroll:http://github.com/cubiq/iscroll(这个用谷歌浏览器打开)
3.5 插件的使用总结
3.6 练习-移动端视频插件zy.media.js
- demo实例文件.html是提前准备的,查看源代码(主要从这里复制码),并找到需要引入哪些文件(zy.media.min.js和zy.media.min.css)
- 具体内容查看lesson7里面的05-视频插件,基本上就是把demo里面的内存抄写到index.html中的