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;
width: 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 {
width: 100%;
}
.focus ul {
overflow: hidden;
/*清除浮動*/
width: 500%;
/*讓ul寬一點,否則就算每個小li添加浮動,也不會在一行顯示*/
margin-left: -100%;
/*讓ul往左走一個focus的寬度,這樣焦點框里初始顯示的才是第一張圖,而不是第三張圖片*/
}
.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: #fff;
list-style: none;
border-radius: 2px;
transition: all .3s;
/*讓小圓點緩慢變化*/
}
.focus ol li.current {
width: 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 {
width: 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中的