移动端浏览器兼容性较好,我们不需要考虑以前JS的兼容性问题,可以放心的使用原生JS书写效果,但是移动端也有自己独特的地方,比如触屏事件touch(也称触摸事件),Android和IOS都有
touch对象代表一个触摸点,触摸点可以是一根手指,也可能是一根触摸笔。触屏事件可相应用户手指(或触控笔)对屏幕或者触控板操作
常见的触屏事件如下:
触屏touch事件 | 说明 |
---|---|
touchstart | 手指触摸到一个DOM元素时触发 |
touchmove | 手指在一个DOM元素上滑动时触发 |
touchend | 手指从一个DOM元素移开时触发 |
TouchEvent是一类描述手指在触摸平面(触摸屏、触摸板等)的状态变化的事件,这类事件用于描述一个或多个触点,使开发者可以检测缺点的移动,触电的增加和减少,等等
touchstart、touchmove、touchend三个事件都会各自有事件对象
div.addEventListener('touchstart', function (e) {
console.log(e);
});
触摸事件对象重点看三个常见对象列表:
触摸列表 | 说明 |
---|---|
touches | 正在触摸屏幕的所有手指的一个列表 |
targetTouches | 正在触摸当前DOM元素上的手指的一个列表 |
changedTouches | 手指状态发生了改变的列表,从无到有,从有到无变化 |
注意:
拖动元素三部曲:
注意:手指移动也会触发滚动屏幕所以这里要阻止默认的屏幕滚动e.preventDefault()
步骤:
-------------------------------------------布局-------------------------------------------------------------------------------
1.把所有的图片放在一个ul的li中
2.设置小圆点,子绝父相
3.当前选中的小圆点长度会变长
4.因为图片显示到最后一张还有在第一张拖动的时候会留白,将第一张图片和倒数第二张图片复制
5.图片一行显示 设置浮动 把ul的宽度设为父元素的百分之500,但是,百分比都是按照父元素来说的,所以每个图片的宽度也会成百分之500,因为图片宽度100%,而图片的父元素li没有设置宽度,父元素的父元素ul设置了宽度(500%),所以图片的宽度和ul相同,所以才会变大,为了解决这个问题,就给图片的父元素li设置宽度,因为一共有5张图片,每个li就设置成父元素的20%
6.因为li设置了浮动,会脱标,影响下面的元素显示,所以清除浮动
7.小圆点设置了margin 清除margin
8.因为一开始显示的是第三张图,为了显示第一张图,把整个ul向左移一个图片的宽度(图片的宽度就是整个父盒子focus的宽度)
注意:
1.
图上写错了,是第一张图片向左拖的时候,会留白
------------------------------------------------自动播放---------------------------------------------------------
步骤:
ul.style.transition = 'all .3s';
注意:
---------------------------------------------无缝滚动-----------------------------------------------------------
步骤:
注意:
----------------------------------------------------------------------------------------------------------------------
classList属性是HTML5新增的一个属性,返回元素的类名。但是ie10以上版本支持
该属性用于在元素中添加,移除及切换CSS类。有以下方法
添加类:
element.classList.add('类名');
focus.classList.add('current');
注意:添加类名,是在后面追加类名,不会覆盖以前的类名 注意前面不要加.
移除类:
element.classList.remove('类名');
切换类:
element.classList.toggle('类名');
原来有这个类名,就删除这个类名,没有这个类名,就给添加这个类名
--------------------------------------------小圆点跟随变化---------------------------------------------
步骤:
----------------------------------------------手指滑动轮播图----------------------------------------------------
步骤:
注意:
--------------------------------------------------------完整代码-----------------------------------------------------------
index.html
携程在手,说走就走 \
搜索:目的地/酒店/景点/航班号
我 的





热门活动
获取更多福利
index.css
body {
max-width: 540px;
min-width: 320px;
margin: 0 auto;
font: normal 14px/1.5 Tahoma, "Lucida Grande", Verdana, "Microsoft Yahei", STXihei, hei;
color: #000;
background: #f2f2f2;
overflow-x: hidden;
-webkit-tap-highlight-color: transparent;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
a {
text-decoration: none;
color: #222;
}
div {
box-sizing: border-box;
}
/* 搜索模块 */
.search-index {
display: flex;
/* 固定定位跟父级没有关系 它以屏幕为准 */
position: fixed;
top: 0;
left: 50%;
z-index: 999;
/* 固定的盒子应该有宽度 */
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
width: 100%;
min-width: 320px;
max-width: 540px;
height: 44px;
/* background-color: pink; */
background-color: #F6F6F6;
border-top: 1px solid #ccc;
border-bottom: 1px solid #ccc;
}
.search {
position: relative;
height: 26px;
line-height: 24px;
border: 1px solid #ccc;
flex: 1;
font-size: 12px;
color: #666;
margin: 7px 10px;
padding-left: 25px;
border-radius: 5px;
box-shadow: 0 2px 4px rgba(0, 0, 0, .2);
}
.search::before {
content: "";
position: absolute;
top: 5px;
left: 5px;
width: 15px;
height: 15px;
background: url(../images/sprite.png) no-repeat -59px -279px;
background-size: 104px auto;
}
.user {
width: 44px;
height: 44px;
/* background-color: purple; */
font-size: 12px;
text-align: center;
color: #2eaae0;
}
.user::before {
content: "";
display: block;
width: 23px;
height: 23px;
background: url(../images/sprite.png) no-repeat -59px -194px;
background-size: 104px auto;
margin: 4px auto -2px;
}
/* goBack */
.goBack {
display: none;
position: fixed;
bottom: 50px;
right: 20px;
width: 38px;
height: 38px;
background: url(../images/back.png) no-repeat;
background-size: 38px 38px;
}
/* focus */
.focus {
overflow: hidden;
position: relative;
padding-top: 44px;
}
.focus img {
width: 100%;
}
.focus ul {
width: 500%;
margin-left: -100%;
}
.focus ul li {
float: left;
width: 20%;
}
.focus ol {
position: absolute;
bottom: 5px;
right: 5px;
margin: 0;
}
.focus ol li {
display: inline-block;
width: 5px;
height: 5px;
background-color: red;
list-style: none;
border-radius: 2px;
}
.focus ol li.current {
width: 15px;
}
/* local-nav */
.local-nav {
display: flex;
height: 64px;
margin: 3px 4px;
background-color: #fff;
border-radius: 8px;
}
.local-nav li {
flex: 1;
}
.local-nav a {
display: flex;
flex-direction: column;
/* 侧轴居中对齐 因为是单行 */
align-items: center;
font-size: 12px;
}
.local-nav li [class^="local-nav-icon"] {
width: 32px;
height: 32px;
background-color: pink;
margin-top: 8px;
background: url(../images/localnav_bg.png) no-repeat 0 0;
background-size: 32px auto;
}
.local-nav li .local-nav-icon-icon2 {
background-position: 0 -32px;
}
.local-nav li .local-nav-icon-icon3 {
background-position: 0 -64px;
}
.local-nav li .local-nav-icon-icon4 {
background-position: 0 -96px;
}
.local-nav li .local-nav-icon-icon5 {
background-position: 0 -128px;
}
/* nav */
nav {
overflow: hidden;
border-radius: 8px;
margin: 0 4px 3px;
}
.nav-common {
display: flex;
height: 88px;
background-color: pink;
}
.nav-common:nth-child(2) {
margin: 3px 0;
}
.nav-items {
/* 不冲突的 */
flex: 1;
display: flex;
flex-direction: column;
}
.nav-items a {
flex: 1;
text-align: center;
line-height: 44px;
color: #fff;
font-size: 14px;
/* 文字阴影 */
text-shadow: 1px 1px rgba(0, 0, 0, .2);
}
.nav-items a:nth-child(1) {
border-bottom: 1px solid #fff;
}
.nav-items:nth-child(1) a {
border: 0;
background: url(../images/hotel.png) no-repeat bottom center;
background-size: 121px auto;
}
/* -n+2就是选择前面两个元素 */
.nav-items:nth-child(-n+2) {
border-right: 1px solid #fff;
}
.nav-common:nth-child(1) {
background: -webkit-linear-gradient(left, #FA5A55, #FA994D);
}
.nav-common:nth-child(2) {
background: -webkit-linear-gradient(left, #4B90ED, #53BCED);
}
.nav-common:nth-child(3) {
background: -webkit-linear-gradient(left, #34C2A9, #6CD559);
}
/* subnav-entry */
.subnav-entry {
display: flex;
border-radius: 8px;
background-color: #fff;
margin: 0 4px;
flex-wrap: wrap;
padding: 5px 0;
}
.subnav-entry li {
/* 里面的子盒子可以写 % 相对于父级来说的 */
flex: 20%;
}
.subnav-entry a {
display: flex;
flex-direction: column;
align-items: center;
}
.subnav-entry-icon {
width: 28px;
height: 28px;
background-color: pink;
margin-top: 4px;
background: url(../images/subnav-bg.png) no-repeat;
background-size: 28px auto;
}
/* sales-box */
.sales-box {
border-top: 1px solid #bbb;
background-color: #fff;
margin: 4px;
}
.sales-hd {
position: relative;
height: 44px;
border-bottom: 1px solid #ccc;
}
.sales-hd h2 {
position: relative;
text-indent: -999px;
overflow: hidden;
}
.sales-hd h2::after {
position: absolute;
top: 5px;
left: 8px;
content: "";
width: 79px;
height: 15px;
background: url(../images/hot.png) no-repeat 0 -20px;
background-size: 79px auto;
}
.more {
position: absolute;
right: 5px;
top: 0px;
background: -webkit-linear-gradient(left, #FF506C, #FF6BC6);
border-radius: 15px;
padding: 3px 20px 3px 10px;
color: #fff;
}
.more::after {
content: "";
position: absolute;
top: 9px;
right: 9px;
width: 7px;
height: 7px;
border-top: 2px solid #fff;
border-right: 2px solid #fff;
transform: rotate(45deg);
}
.row {
display: flex;
}
.row a {
flex: 1;
border-bottom: 1px solid #eee;
}
.row a:nth-child(1) {
border-right: 1px solid #eee;
}
.row a img {
width: 100%;
}
index.js
window.addEventListener('load', function () {
// 1.获取元素
var focus = document.querySelector('.focus');
var ul = focus.children[0];
var w = focus.offsetWidth; //图片的宽度,即focus的宽度
var index = 0;
var ol = focus.children[1];
var flag = false; //标志位,判断用户有没有移动手指
// 2.利用定时器自动轮播图片
var timer = setInterval(function () {
index++;
var transformx = -index * w;
ul.style.transition = 'all .3s';
ul.style.transform = 'translateX(' + transformx + 'px)';
}, 2000);
// 3.实现无缝滚动
// 等待过渡完成
ul.addEventListener('transitionend', function () {
if (index >= ul.children.length - 2) {
index = 0;
// 去掉过渡效果 这样让我们的ul快速的跳到目标位置
ul.style.transition = 'none';
// 利用最新的索引号乘以宽度,去滚动图片
var transformx = -index * w;
ul.style.transform = 'translateX(' + transformx + 'px)';
} else if (index < 0) {
index = ul.children.length - 3;
ul.style.transition = 'none';
var transformx = -index * w;
ul.style.transform = 'translateX(' + transformx + 'px)';
}
// 小圆点跟随变化
ol.querySelector('.current').classList.remove('current');
ol.children[index].classList.add('current');
});
//4.手指拖动图片
var startX = 0; //手指起始的距离
var moveX = 0; //手指滑动的距离
ul.addEventListener('touchstart', function (e) {
startX = e.targetTouches[0].pageX;
// 手指触摸的时候停止定时器
clearInterval(timer);
});
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(); //阻止屏幕滚动的默认行为
});
//5.手指离开,根据移动的距离去判断回弹还是播放上一张下一张
ul.addEventListener('touchend', function () {
if (flag) {
// 如果移动的距离超过50 就去播放上一张/下一张
if (Math.abs(moveX) > 50) {
// 如果右滑就是播放上一张 moveX是正值
if (moveX > 0) {
index--;
} else {
// 如果左滑就是播放上一张 moveX是负值
index++;
}
var translatex = -index * w;
ul.style.transition = 'all .3s';
ul.style.transform = 'translateX(' + translatex + 'px)';
} else {
// 如果移动距离不超过50就回弹(回到原来的距离)
var translatex = -index * w;
ul.style.transition = 'all .1s';
ul.style.transform = 'translateX(' + translatex + 'px)';
}
}
// 再开启定时器
clearInterval();
timer = setInterval(function () {
index++;
var transformx = -index * w;
ul.style.transition = 'all .3s';
ul.style.transform = 'translateX(' + transformx + 'px)';
}, 2000);
});
})
------------------------------------------运行效果-----------------------------------------------------------------------