溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

HTML5觸摸事件演化tap事件的示例分析

發(fā)布時(shí)間:2021-09-15 15:44:18 來源:億速云 閱讀:145 作者:柒染 欄目:web開發(fā)

HTML5觸摸事件演化tap事件介紹,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。

觸摸事件是移動(dòng)瀏覽器特有的HTML5事件,雖然click事件在pc和移動(dòng)端更通用,但是在移動(dòng)端會(huì)出現(xiàn)300ms延遲,較為影響用戶體驗(yàn),300ms延遲來自判斷雙擊和長按,因?yàn)橹挥心J(rèn)等待時(shí)間結(jié)束以確定沒有后續(xù)動(dòng)作發(fā)生時(shí),才會(huì)觸發(fā)click事件。所以觸摸事件反應(yīng)更快,體驗(yàn)更好。

HTML5觸摸事件演化tap事件的示例分析

觸摸事件的類型:

為了區(qū)別觸摸相關(guān)的狀態(tài)改變,存在多種類型的觸摸事件??梢酝ㄟ^檢查觸摸事件的 TouchEvent.type 屬性來確定當(dāng)前事件屬于哪種類型。

注意: 在很多情況下,觸摸事件和鼠標(biāo)事件會(huì)同時(shí)被觸發(fā)(目的是讓沒有對(duì)觸摸設(shè)備優(yōu)化的代碼仍然可以在觸摸設(shè)備上正常工作)。如果你使用了觸摸事件,可以調(diào)用 event.preventDefault() 來阻止鼠標(biāo)事件被觸發(fā)。

標(biāo)準(zhǔn)的觸摸事件

事件名稱描述包含touches數(shù)組

touchstart

當(dāng)用戶在觸摸平面上放置了一個(gè)觸點(diǎn)時(shí)觸發(fā)。事件的目標(biāo) element 將是觸點(diǎn)位置上的那個(gè)目標(biāo) element

touchmove

當(dāng)用戶在觸摸平面上移動(dòng)觸點(diǎn)時(shí)觸發(fā)。

事件的目標(biāo) element 和這個(gè) touchmove 事件對(duì)應(yīng)的 touchstart 事件的目標(biāo) element 相同,

哪怕當(dāng) touchmove 事件觸發(fā)時(shí),觸點(diǎn)已經(jīng)移出了該 element 。

touchend

當(dāng)一個(gè)觸點(diǎn)被用戶從觸摸平面上移除(當(dāng)用戶將一個(gè)手指離開觸摸平面)時(shí)觸發(fā)。

當(dāng)觸點(diǎn)移出觸摸平面的邊界時(shí)也將觸發(fā)。例如用戶將手指劃出屏幕邊緣。

已經(jīng)被從觸摸平面上移除的觸點(diǎn),可以在 changedTouches 屬性定義的 TouchList 中找到。

touchenter

當(dāng)觸點(diǎn)進(jìn)入某個(gè) element 時(shí)觸發(fā)。此事件沒有冒泡過程。

touchleave

當(dāng)觸點(diǎn)離開某個(gè) element 時(shí)觸發(fā)。此事件沒有冒泡過程。

touchcancel

當(dāng)觸點(diǎn)由于某些原因被中斷時(shí)觸發(fā)。有幾種可能的原因如下(具體的原因根據(jù)不同的設(shè)備和瀏覽器有所不同):

  • 由于某個(gè)事件取消了觸摸:例如觸摸過程被一個(gè)模態(tài)的彈出框打斷。

  • 觸點(diǎn)離開了文檔窗口,而進(jìn)入了瀏覽器的界面元素、插件或者其他外部內(nèi)容區(qū)域。

  • 當(dāng)用戶產(chǎn)生的觸點(diǎn)個(gè)數(shù)超過了設(shè)備支持的個(gè)數(shù),從而導(dǎo)致 TouchList 中最早的 Touch 對(duì)象被取消。

觸摸對(duì)象屬性

Touch.identifier返回一個(gè)可以唯一地識(shí)別和觸摸平面接觸的點(diǎn)的值. 這個(gè)值在這根手指(或觸摸筆等)所引發(fā)的所有事件中保持一致, 直到它離開觸摸平面.
Touch.screenX觸點(diǎn)相對(duì)于屏幕左邊沿的的X坐標(biāo). 只讀屬性.
Touch.screenY觸點(diǎn)相對(duì)于屏幕上邊沿的的Y坐標(biāo). 只讀屬性.
Touch.clientX觸點(diǎn)相對(duì)于可見視區(qū)左邊沿的的X坐標(biāo). 不包括任何滾動(dòng)偏移. 只讀屬性.
Touch.clientY觸點(diǎn)相對(duì)于可見視區(qū)上邊沿的的Y坐標(biāo). 不包括任何滾動(dòng)偏移. 只讀屬性.
Touch.pageX觸點(diǎn)相對(duì)于HTML文檔左邊沿的的X坐標(biāo). 當(dāng)存在水平滾動(dòng)的偏移時(shí), 這個(gè)值包含了水平滾動(dòng)的偏移只讀屬性.
Touch.pageY觸點(diǎn)相對(duì)于HTML文檔上邊沿的的Y坐標(biāo). 當(dāng)存在水平滾動(dòng)的偏移時(shí), 這個(gè)值包含了垂直滾動(dòng)的偏移只讀屬性.
Touch.radiusX能夠包圍用戶和觸摸平面的接觸面的最小橢圓的水平軸(X軸)半徑. 這個(gè)值的單位和 screenX 相同. 只讀屬性.
Touch.force手指擠壓觸摸平面的壓力大小, 從0.0(沒有壓力)到1.0(最大壓力)的浮點(diǎn)數(shù). 只讀屬性.
Touch.radiusY能夠包圍用戶和觸摸平面的接觸面的最小橢圓的垂直軸(Y軸)半徑. 這個(gè)值的單位和 screenY 相同. 只讀屬性.
Touch.target

當(dāng)這個(gè)觸點(diǎn)最開始被跟蹤時(shí)(在 touchstart 事件中), 觸點(diǎn)位于的HTML元素. 哪怕在觸點(diǎn)移動(dòng)過程中, 觸點(diǎn)的位置已經(jīng)離開了這個(gè)元素的有效交互區(qū)域,

或者這個(gè)元素已經(jīng)被從文檔中移除. 需要注意的是, 如果這個(gè)元素在觸摸過程中被移除, 這個(gè)事件仍然會(huì)指向它, 但是不會(huì)再冒泡這個(gè)事件到 window 或 document 對(duì)象.

因此, 如果有元素在觸摸過程中可能被移除, 最佳實(shí)踐是將觸摸事件的監(jiān)聽器綁定到這個(gè)元素本身, 防止元素被移除后, 無法再從它的上一級(jí)元素上偵測(cè)到從該元素冒泡的事件. 只讀屬性.

IE10+的觸摸事件

IE指針事件
事件名稱描述(在觸摸設(shè)備上)
MSPointerDown觸摸開始
MSPointerMove接觸點(diǎn)移動(dòng)
MSPointerUp觸摸結(jié)束
MSPointerOver觸摸點(diǎn)移動(dòng)到元素內(nèi),相當(dāng)于mouseover
MSPointerOut觸摸點(diǎn)離開元素,相當(dāng)于mouseout

MSPointerEvent屬性

屬性描述
hwTimestamp創(chuàng)建事件的時(shí)間(ms)
isPrimary標(biāo)識(shí)該指針是不是主指針
pointerId指針的唯一ID(類似于觸摸事件的標(biāo)識(shí)符)
pointerType一個(gè)整數(shù),標(biāo)識(shí)了該事件來自鼠標(biāo)、手寫筆還是手指
pressure筆的壓力,0-255,只有手寫筆輸入時(shí)才可用
rotation0-359的整數(shù),光標(biāo)的旋轉(zhuǎn)度(如果支持的話)
tiltX/tiltY手寫筆的傾斜度,只有用手寫筆輸入時(shí)才支持

等價(jià)事件

鼠標(biāo)觸摸鍵盤
mousedowntouchstartkeydown
mousemovetouchmovekeydown
mouseuptouchendkeyup
mouseover focus

很顯然,觸摸動(dòng)作序列:touchstart-touchmove-touchend和鼠標(biāo)序 列:mousedown-mousemove-mouseup以及鍵盤序列:keydown-keypress-keyup很相似,這并不是巧合,因?yàn)檫@ 三種交互模式都可以描述為start-move-stop。

話說回來,click要經(jīng)過touchstart-touchmove-touchend流程,300ms延遲,所以需要tap事件,tap就是在同一個(gè)點(diǎn)輕觸時(shí)間很短。

封裝好的tap和longtap事件

XML/HTML Code復(fù)制內(nèi)容到剪貼板

  1. (function() {    
        var TOUCHSTART, TOUCHEND;    
        if (typeof(window.ontouchstart) != 'undefined') {    
            TOUCHSTART = 'touchstart';    
            TOUCHEND = 'touchend';    
            TOUCHMOVE='touchmove';    
         
        } else if (typeof(window.onmspointerdown) != 'undefined') {    
            TOUCHSTART = 'MSPointerDown';    
            TOUCHEND = 'MSPointerUp';    
            TOUCHMOVE='MSPointerMove';    
        } else {    
            TOUCHSTART = 'mousedown';    
            TOUCHEND = 'mouseup';    
            TOUCHMOVE = 'mousemove';    
        }    
        function NodeTouch(node) {    
            this._node = node;    
        }    
        function tap(node,callback,scope) {    
            node.addEventListener(TOUCHSTART, function(e) {    
                x = e.touches[0].pageX;    
                y = e.touches[0].pageY;    
            });    
            node.addEventListener(TOUCHEND, function(e) {    
                e.stopPropagation();    
                e.preventDefault();    
                var curx = e.changedTouches[0].pageX;    
                var cury = e.changedTouches[0].pageY;    
                if (Math.abs(curx - x) < 6 && Math.abs(cury - y) < 6) {    
                    callback.apply(scope, arguments);    
                }    
            });    
        }    
        function longTap(node,callback,scope) {    
            var x,y,startTime=0,endTime=0,in_dis=false;    
            node.addEventListener(TOUCHSTART, function(e) {    
                x = e.touches[0].pageX;    
                y = e.touches[0].pageY;    
                startTime=(new Date()).getTime();    
            });    
            node.addEventListener(TOUCHEND, function(e) {    
                e.stopPropagation();    
                e.preventDefault();    
                var curx = e.changedTouches[0].pageX;    
                var cury = e.changedTouches[0].pageY;    
                if (Math.abs(curx - x) < 6 && Math.abs(cury - y) < 6) {    
                    in_dis=true;    
                }else{    
                    in_dis=false;    
                }    
                endTime=(new Date()).getTime();    
                if (endTime - startTime > 300 && in_dis) {    
                    callback.apply(scope, arguments);    
                }    
            });    
        }    
        NodeTouch.prototype.on = function(evt, callback, scope) {    
            var scopeObj;    
            var x,y;    
            if (!scope) {    
                scopeObj = this._node;    
            } else {    
                scopescopeObj = scope;    
            }    
            if (evt === 'tap') {    
                tap(this._node,callback,scope);    
            } else if(evt === 'longtap'){    
                longTap(this._node,callback,scope);    
            } else {    
                this._node.addEventListener(evt, function() {    
                    callback.apply(scope, arguments);    
                });    
            }    
            return this;    
        }    
        window.$ = function(selector) {    
            var node = document.querySelector(selector);    
            if (node) {    
                return new NodeTouch(node);    
            } else {    
                return null;    
            }    
        }    
    })();    
    var box=$("#box");    
    box.on("longtap",function(){    
        console.log("你已經(jīng)長按了");    
    },box)

看完上述內(nèi)容,你們掌握HTML5觸摸事件演化tap事件介紹的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI