Javascript-API-BOM、觸屏事件、移動端輪播圖解析、classList屬性、click 延時解決方案、本地存儲

觸屏事件

  • 觸屏事件概述

移動端瀏覽器兼容性較好,我們不需要考慮以前 JS 的兼容性問題,可以放心的使用原生 JS 書寫效果,但是移動端也有自己獨特的地方。比如觸屏事件 touch(也稱觸摸事件),Android和 IOS 都有。
touch 對象代表一個觸摸點。觸摸點可能是一根手指,也可能是一根觸摸筆。觸屏事件可響應用戶手指(或觸控筆)對屏幕或者觸控板操作。

常見的觸屏事件如下:
觸屏事件

  • 觸摸事件對象(TouchEvent)

TouchEvent
是一類描述手指在觸摸平面(觸摸屏、觸摸板等)的狀態變化的事件。這類事件用於描述一個或多個觸點,使開發者可以檢測觸點的移動,觸點的增加和減少,等等

在這裏插入圖片描述
因爲平時我們都是給元素註冊觸摸事件,所以重點記住 targetTocuhes

  • 案例:移動端拖動元素
  1. touchstart、touchmove、touchend可以實現拖動元素
  2. 但是拖動元素需要當前手指的座標值 我們可以使用 targetTouches[0] 裏面的pageX 和 pageY
  3. 移動端拖動的原理: 手指移動中,計算出手指移動的距離。然後用盒子原來的位置 + 手指移動的距離
  4. 手指移動的距離: 手指滑動中的位置 減去 手指剛開始觸摸的位置

拖動元素三步曲:

(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>

移動端常見特效

  • 移動端輪播圖案例
  1. 可以自動播放圖片
  2. 手指可以拖動播放輪播圖
    移動端輪播圖功能和基本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) 頁面。

解決方案:

  1. 禁用縮放。 瀏覽器禁用默認的雙擊縮放行爲並且去掉300ms 的點擊延遲。
<meta name="viewport" content="user-scalable=no">

2.利用touch事件自己封裝這個事件解決300ms 延遲。

原理就是:

  1. 當我們手指觸摸屏幕,記錄當前觸摸時間
  2. 當我們手指離開屏幕, 用離開的時間減去觸摸的時間
  3. 如果時間小於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、以鍵值對的形式存儲使用

記住用戶名案例

  1. 把數據存起來,用到本地存儲
  2. 關閉頁面,也可以顯示用戶名,所以用到localStorage
  3. 打開頁面,先判斷是否有這個用戶名,如果有,就在表單裏面顯示用戶名,並且勾選複選框
  4. 當複選框發生改變的時候change事件
  5. 如果勾選,就存儲,否則就移除
<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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章