觸屏事件
- 觸屏事件概述
移動端瀏覽器兼容性較好,我們不需要考慮以前 JS 的兼容性問題,可以放心的使用原生 JS 書寫效果,但是移動端也有自己獨特的地方。比如觸屏事件 touch(也稱觸摸事件),Android和 IOS 都有。
touch 對象代表一個觸摸點。觸摸點可能是一根手指,也可能是一根觸摸筆。觸屏事件可響應用戶手指(或觸控筆)對屏幕或者觸控板操作。
常見的觸屏事件如下:
- 觸摸事件對象(TouchEvent)
TouchEvent
是一類描述手指在觸摸平面(觸摸屏、觸摸板等)的狀態變化的事件。這類事件用於描述一個或多個觸點,使開發者可以檢測觸點的移動,觸點的增加和減少,等等
因爲平時我們都是給元素註冊觸摸事件,所以重點記住 targetTocuhes
- 案例:移動端拖動元素
- touchstart、touchmove、touchend可以實現拖動元素
- 但是拖動元素需要當前手指的座標值 我們可以使用 targetTouches[0] 裏面的pageX 和 pageY
- 移動端拖動的原理: 手指移動中,計算出手指移動的距離。然後用盒子原來的位置 + 手指移動的距離
- 手指移動的距離: 手指滑動中的位置 減去 手指剛開始觸摸的位置
拖動元素三步曲:
(1) 觸摸元素 touchstart: 獲取手指初始座標,同時獲得盒子原來的位置
(2) 移動手指 touchmove: 計算手指的滑動距離,並且移動盒子
(3) 離開手指 touchend:
注意: 手指移動也會觸發滾動屏幕所以這裏要阻止默認的屏幕滾動e.preventDefault()
;
<style>
div {
position: absolute;
left: 0;
width: 100px;
height: 100px;
background-color: pink;
}
</style>
</head>
<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;
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>
移動端常見特效
。
- 移動端輪播圖案例
- 可以自動播放圖片
- 手指可以拖動播放輪播圖
移動端輪播圖功能和基本PC端一致
window.addEventListener('load', function() {
//1. 自動播放功能
//2. 開啓定時器
//3. 移動端移動,可以使用translate 移動
//4. 想要圖片優雅的移動,請添加過渡效果
// alert(1);
// 1. 獲取元素
var focus = document.querySelector('.focus');
var ul = focus.children[0];
// 獲得focus 的寬度
var w = focus.offsetWidth;
console.log(w);
var ol = focus.children[1];
// 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
// 1. 自動播放功能-無縫滾動
//2. 注意,我們判斷條件是要等到圖片滾動完畢再去判斷,就是過渡完成後判斷
//3. 此時需要添加檢測過渡完成事件 transitionend
//4. 判斷條件:如果索引號等於 3 說明走到最後一張圖片,此時 索引號要復原爲 0
//5. 此時圖片,去掉過渡效果,然後移動
//6. 如果索引號小於0, 說明是倒着走, 索引號等於2
//7. 此時圖片,去掉過渡效果,然後移動
ul.addEventListener('transitionend', function() {
// 無縫滾動
if (index >= 3) {
index = 0;
// console.log(index);
// 去掉過渡效果 這樣讓我們的ul 快速的跳到目標位置
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
// 1. 小圓點跟隨變化效果
//2. 把ol裏面li帶有current類名的選出來去掉類名 remove
//3. 讓當前索引號的小li 加上 current add
//4. 但是,是等着過渡結束之後變化,所以這個寫到 transitionend 事件裏面
ol.querySelector('.current').classList.remove('current');
// 讓當前索引號 的小li 加上 current add
ol.children[index].classList.add('current');
});
// 4. 手指滑動輪播圖
//1. 手指滑動輪播圖
//2. 本質就是ul跟隨手指移動,簡單說就是移動端拖動元素
//3. 觸摸元素touchstart: 獲取手指初始座標
//4. 移動手指touchmove: 計算手指的滑動距離,並且移動盒子
//5. 離開手指touchend: 根據滑動的距離分不同的情況
//6. 如果移動距離小於某個像素 就回彈原來位置
//7. 如果移動距離大於某個像素就上一張下一張滑動。
//8. 滑動也分爲左滑動和右滑動判斷的標準是 移動距離正負 如果是負值就是左滑 反之右滑
//9. 如果是左滑就播放下一張 (index++)
//10. 如果是右滑就播放上一張 (index--)
// 觸摸元素 touchstart: 獲取手指初始座標
var startX = 0;
var moveX = 0; // 後面我們會使用這個移動距離所以要定義一個全局變量
var flag = false;
ul.addEventListener('touchstart', function(e) {
//鼠標觸摸時在頁面中的位置
startX = e.targetTouches[0].pageX;
// 手指觸摸的時候就停止定時器
clearInterval(timer);
});
// 移動手指 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) {
// (1) 如果移動距離大於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 {
// (2) 如果移動距離小於50像素我們就回彈
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);
});
// 返回頂部模塊製作
// 1. 滾動某個地方顯示
//2. 事件:scroll頁面滾動事件
//3. 如果被捲去的頭部(window.pageYOffset )大於某個數值
//4. 點擊,window.scroll(0,0) 返回頂部
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);
})
})
classList 屬性
classList屬性是HTML5新增的一個屬性,返回元素的類名。但是ie10以上版本支持。
該屬性用於在元素中添加,移除及切換 CSS 類。有以下方法
添加類:
element.classList.add(’類名’);
focus.classList.add('current');
移除類:
element.classList.remove(’類名’);
focus.classList.remove('current');
切換類:
element.classList.toggle(’類名’);
focus.classList.toggle('current');
注意:以上方法裏面,所有類名都不帶點
click 延時解決方案
移動端 click 事件會有 300ms 的延時,原因是移動端屏幕雙擊會縮放(double tap to zoom) 頁面。
解決方案:
- 禁用縮放。 瀏覽器禁用默認的雙擊縮放行爲並且去掉300ms 的點擊延遲。
<meta name="viewport" content="user-scalable=no">
2.利用touch事件自己封裝這個事件解決300ms 延遲。
原理就是:
- 當我們手指觸摸屏幕,記錄當前觸摸時間
- 當我們手指離開屏幕, 用離開的時間減去觸摸的時間
- 如果時間小於150ms,並且沒有滑動過屏幕, 那麼我們就定義爲點擊
//封裝tap,解決click 300ms 延時
function tap (obj, callback) {
var isMove = false;
var startTime = 0; // 記錄觸摸時候的時間變量
obj.addEventListener('touchstart', function (e) {
startTime = Date.now(); // 記錄觸摸時間
});
obj.addEventListener('touchmove', function (e) {
isMove = true; // 看看是否有滑動,有滑動算拖拽,不算點擊
});
obj.addEventListener('touchend', function (e) {
if (!isMove && (Date.now() - startTime) < 150) { // 如果手指觸摸和離開時間小於150ms 算點擊
callback && callback(); // 執行回調函數
}
isMove = false; // 取反 重置
startTime = 0;
});
}
//調用
tap(div, function(){ // 執行代碼 });
- 3 使用插件。fastclick 插件解決300ms 延遲。
本地存儲
- 本地存儲特性
1、數據存儲在用戶瀏覽器中
2、設置、讀取方便、甚至頁面刷新不丟失數據
3、容量較大,sessionStorage約5M、localStorage約20M
4、只能存儲字符串,可以將對象JSON.stringify() 編碼後存儲
- indow.sessionStorage
1、生命週期爲關閉瀏覽器窗口
2、在同一個窗口(頁面)下數據可以共享
3、以鍵值對的形式存儲使用
存儲數據:
sessionStorage.setItem(key, value)
獲取數據:
sessionStorage.getItem(key)
刪除數據:
sessionStorage.removeItem(key)
清空數據:(所有都清除掉)
sessionStorage.clear()
- window.localStorage\
1、聲明週期永久生效,除非手動刪除 否則關閉頁面也會存在
2、可以多窗口(頁面)共享(同一瀏覽器可以共享)
3、以鍵值對的形式存儲使用
記住用戶名案例
- 把數據存起來,用到本地存儲
- 關閉頁面,也可以顯示用戶名,所以用到localStorage
- 打開頁面,先判斷是否有這個用戶名,如果有,就在表單裏面顯示用戶名,並且勾選複選框
- 當複選框發生改變的時候change事件
- 如果勾選,就存儲,否則就移除
<body>
<input type="text" id="username"> <input type="checkbox" name="" id="remember"> 記住用戶名
<script>
var username = document.querySelector('#username');
var remember = document.querySelector('#remember');
if (localStorage.getItem('username')) {
username.value = localStorage.getItem('username');
remember.checked = true;
}
remember.addEventListener('change', function() {
if (this.checked) {
localStorage.setItem('username', username.value)
} else {
localStorage.removeItem('username');
}
})
</script>
</body>