欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

移動(dòng)web開(kāi)發(fā)技能之touch事件詳解

 更新時(shí)間:2022年09月03日 11:09:47   作者:呂小鳴  
這篇文章主要為大家介紹了移動(dòng)web開(kāi)發(fā)技能之touch事件詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

概述

單擊事件是任何一個(gè)前端頁(yè)面中最常用的交互行為之一,在傳統(tǒng)的PC端大部分是使用click事件來(lái)實(shí)現(xiàn)用戶單擊交互的程序邏輯,而在移動(dòng)Web端新增了touch事件來(lái)實(shí)現(xiàn)移動(dòng)端更加敏感和復(fù)雜的觸摸交互行為。本章將就移動(dòng)端touch事件的使用以及它與PC端的click事件的區(qū)別進(jìn)行深入探討。

touch事件

在傳統(tǒng)的PC端,用戶的單擊操作主要是由鼠標(biāo)的左鍵或者右鍵來(lái)產(chǎn)生,它主要是指鼠標(biāo)的按鈕被按下,并且在很短的時(shí)間內(nèi)(一般小于300ms)又被釋放開(kāi),這就被稱為單擊操作(或稱為一次點(diǎn)擊操作)。

而對(duì)于移動(dòng)Web端,同樣也是如此,當(dāng)手指觸摸到屏幕時(shí)開(kāi)始計(jì)算時(shí)間,并且在300ms內(nèi)離開(kāi)屏幕,這段時(shí)間手指不能移動(dòng),這就算是移動(dòng)Web端的單擊事件,手指觸摸就被稱為touch。

touch事件分類

移動(dòng)Web端的touch觸摸事件主要由屏幕和觸摸點(diǎn)組成,其中屏幕可以是手機(jī)、平板或者觸摸板,而觸摸點(diǎn)可以通過(guò)手指、胳膊肘或觸摸筆,甚至耳朵、鼻子都行,但一般是通過(guò)手指。根據(jù)touch觸摸的類型可分為以下4種事件:

  • touchstart:當(dāng)手指與屏幕接觸時(shí)觸發(fā)。
  • touchmove:當(dāng)手指在屏幕上滑動(dòng)時(shí)連續(xù)地觸發(fā)。
  • touchend:當(dāng)手指從屏幕上離開(kāi)時(shí)觸發(fā)。
  • touchcancel:當(dāng)touch事件被迫終止,例如電話接入或者彈出信息時(shí)會(huì)觸發(fā),或者當(dāng)觸摸點(diǎn)太多,超過(guò)了支持的上限(自動(dòng)取消早先的觸摸點(diǎn))時(shí)觸發(fā),一般不常用。

相比PC端,以上4種事件將用戶的touch行為劃分得更細(xì),并且通過(guò)這些細(xì)化的事件可以實(shí)現(xiàn)移動(dòng)Web端獨(dú)有的用戶交互行為,例如拖動(dòng)swipe、長(zhǎng)按longtap、雙指縮放pinch,等等。

其中的touchstart、touchmove和touchend是最常用的3個(gè)事件,其中touchstart最先觸發(fā),touchend結(jié)束時(shí)觸發(fā),而touchmove是否觸發(fā)取決于手指是否在觸摸屏上移動(dòng)。下面用代碼來(lái)感受一下這3種事件的觸發(fā)順序,如下

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  <title>touch事件</title>
  <script type="text/javascript">
    document.addEventListener("touchstart",function () {
        console.log("開(kāi)始觸摸");
    });
    document.addEventListener("touchmove",function () {
        console.log("移動(dòng)手指");
    });
    document.addEventListener("touchend",function () {
        console.log("結(jié)束觸摸")
    });
  </script>
</head>
<body>
</body>
</html>

在瀏覽器中運(yùn)行這段代碼,同時(shí)注意要啟用Chrome中DevTools工具中的Device Mode功能,并使用鼠標(biāo)模擬手指在屏幕上觸發(fā)觸摸事件,隨后就會(huì)在Console控制臺(tái)看到打印出對(duì)應(yīng)的日志,從中可以看到一個(gè)簡(jiǎn)單的觸摸操作是如何完成的。

touch事件對(duì)象

對(duì)于touch事件,每一次觸發(fā)都可以得到一個(gè)事件對(duì)象,在JavaScript中這個(gè)對(duì)象叫作TouchEvent,利用TouchEvent可以獲取touch事件觸發(fā)時(shí)的坐標(biāo)、元素以及到底有幾個(gè)手指觸發(fā)等,下面就來(lái)了解一下TouchEvent事件對(duì)象。

可以在Console控制臺(tái)打印出當(dāng)前觸發(fā)touch時(shí)的TouchEvent對(duì)象,代碼如下所示:

document.addEventListener("touchstart",function (e) {
    console.log(e);
});

打印的內(nèi)容如圖:

在上面的TouchEvent的屬性中,經(jīng)常使用的就是touches、targetTouches和changedTouches,它們的含義分別是:

  • touches:當(dāng)前頁(yè)面(屏幕)上所有的觸摸點(diǎn)。
  • targetTouches:當(dāng)前綁定事件的元素上的觸摸點(diǎn)。
  • changedTouches:當(dāng)前屏幕上剛剛接觸的手指或者離開(kāi)的手指的觸摸點(diǎn)。

這3個(gè)屬性返回的是TouchList對(duì)象,代表的是一個(gè)touch的集合數(shù)組,也就是說(shuō)每一次touch觸發(fā),都會(huì)兼顧到多指觸摸的場(chǎng)景,下面就分別以單指觸摸的場(chǎng)景和多指觸摸的場(chǎng)景來(lái)講解這3個(gè)屬性的區(qū)別。

首先是單指觸摸的場(chǎng)景,我們來(lái)模擬用戶一個(gè)手指觸摸,如圖。

外層的線框代表頁(yè)面,里面的一個(gè)<div>元素綁定了touch事件,1號(hào)手指觸摸了該<div>元素,這時(shí)touches、targetTouches以及changedTouches里面的觸摸點(diǎn)都是指1號(hào)手指這個(gè)觸摸點(diǎn),應(yīng)該很好理解。 對(duì)于多指觸摸的場(chǎng)景,條件是手指觸摸屏幕之后暫不離開(kāi),如圖。

外層的線框代表頁(yè)面,里面的一個(gè)<div>元素綁定了touch事件,首先1號(hào)手指第一個(gè)觸摸了該<div>元素,然后2號(hào)手指第二個(gè)也觸摸了該<div>元素,最后3號(hào)手指第三個(gè)觸摸了div外面的區(qū)域,這時(shí)touches涵蓋的觸摸點(diǎn)的集合數(shù)組包括1號(hào)、2號(hào)、3號(hào)手指,而targetTouches涵蓋的觸摸點(diǎn)的集合數(shù)組包括1號(hào)和2號(hào)手指,而changedTouches涵蓋的觸摸點(diǎn)的集合數(shù)組包括2號(hào)和3號(hào)手指。

當(dāng)手指都離開(kāi)屏幕之后,touches和targetTouches中將不會(huì)再有值,changedTouches還會(huì)有一個(gè)值,此值為最后一個(gè)離開(kāi)屏幕的手指的接觸點(diǎn)。這就是touches、targetTouches和changedTouches這3個(gè)屬性對(duì)于單指觸摸的場(chǎng)景和多指觸摸的場(chǎng)景下的區(qū)別,總結(jié)如下:

單指觸摸的場(chǎng)景:

  • touches:1號(hào)手指
  • targetTouches:1號(hào)手指
  • changedTouches:1號(hào)手指

多指觸摸的場(chǎng)景:

  • touches:1,2,3號(hào)手指
  • targetTouches:1,2號(hào)手指
  • changedTouches:2,3號(hào)手指

對(duì)于單指觸摸的場(chǎng)景來(lái)說(shuō),它們并無(wú)區(qū)別,主要區(qū)別在于多指觸摸的場(chǎng)景,所以在使用時(shí)可以根據(jù)具體的程序邏輯來(lái)選擇使用合適的屬性。

對(duì)于涵蓋觸摸點(diǎn)的集合數(shù)組TouchList而言,里面每個(gè)元素都是一個(gè)touch對(duì)象,通過(guò)這個(gè)對(duì)象可以獲取當(dāng)前觸摸的位置,如圖。

其中,主要用到了offsetX/Y、pageX/Y和clientX/Y這3個(gè)屬性,它們的區(qū)別和含義分別是:

  • offsetX/Y:觸摸位置相當(dāng)于事件源元素的位置坐標(biāo),以當(dāng)前<div>元素盒子模型的內(nèi)容區(qū)域的左上角為原點(diǎn)。
  • pageX/Y:觸摸位置相當(dāng)于整個(gè)頁(yè)面內(nèi)容區(qū)域的位置坐標(biāo),當(dāng)頁(yè)面過(guò)長(zhǎng)時(shí),包括滾動(dòng)隱藏的部分內(nèi)容,以頁(yè)面完整內(nèi)容區(qū)域的左上角為原點(diǎn)。
  • clientX/Y:觸摸位置相當(dāng)于瀏覽器視區(qū)(屏幕)區(qū)域的位置坐標(biāo),以相對(duì)于頁(yè)面的可見(jiàn)部分內(nèi)容區(qū)域的左上角為原點(diǎn)。

具體的位置和距離可以參考下圖,外層表示頁(yè)面的所有內(nèi)容,中間框表示瀏覽器的視區(qū),其中有一個(gè)<div>元素綁定了touch事件,黑點(diǎn)表示觸摸點(diǎn)的位置。

移動(dòng)web單擊事件

在了解了touch事件之后,我們知道移動(dòng)Web端的單擊事件完全可以由touchstart、touchmove和touchend來(lái)組合實(shí)現(xiàn),移動(dòng)Web端同時(shí)也提供了原生的click事件,它和傳統(tǒng)的PC端的click事件一樣,在用戶完成一次完整的手指單擊屏幕之后觸發(fā)。在移動(dòng)Web端使用click綁定單擊事件,代碼如下:

document.addEventListener("click",function (e) {
    console.log(e);
});

一切看似都很順利,在需要使用單擊時(shí)就用click事件,在需要使用touch時(shí)(拖動(dòng),長(zhǎng)按等)就使用touch對(duì)應(yīng)的事件。但是,對(duì)于移動(dòng)Web端而言,處于iOS系統(tǒng)或Android系統(tǒng)時(shí),采用click實(shí)現(xiàn)單擊事件卻有著不同的表現(xiàn)。

iOS單擊延遲

這要追溯至2007年初,蘋果公司在發(fā)布首款iPhone前遇到了一個(gè)問(wèn)題:當(dāng)時(shí)的網(wǎng)站都是為大屏幕設(shè)備所設(shè)計(jì)的,于是提出了視區(qū)(Viewport)的概念,其中一項(xiàng)即是用戶在瀏覽網(wǎng)頁(yè)時(shí),可以在頁(yè)面的任何地方通過(guò)雙擊操作將頁(yè)面放大(Double Tap to Zoom)。這個(gè)交互功能提升了用戶瀏覽網(wǎng)頁(yè)時(shí)的體驗(yàn),于是Android和iOS的移動(dòng)端瀏覽器紛紛支持了這個(gè)功能,但是對(duì)于雙擊這個(gè)操作而言,其實(shí)是包括了兩次單擊操作,當(dāng)?shù)谝淮螁螕敉瓿珊?,系統(tǒng)需要有一段時(shí)間來(lái)監(jiān)聽(tīng)是否有第二次單擊,如果有則表明此次操作是一個(gè)雙擊操作,而這段時(shí)間間隔大概有300毫秒(ms)。

因此,哪怕是只想要單擊這個(gè)事件,也都會(huì)經(jīng)過(guò)雙擊放大這個(gè)判斷邏輯,導(dǎo)致要等到300毫秒之后才能收到單擊事件程序邏輯的反饋,這就是300毫秒的單擊延遲問(wèn)題。

對(duì)于Android系統(tǒng)的瀏覽器而言,可以通過(guò)給視區(qū)設(shè)置user-scalable=no來(lái)禁止用戶進(jìn)行縮放,隨后就可以正常地使用原生的click事件而沒(méi)有延遲;對(duì)于iOS系統(tǒng)而言,瀏覽器對(duì)user-scalable支持度存在Bug(漏洞),導(dǎo)致了無(wú)法通過(guò)簡(jiǎn)單的設(shè)置來(lái)達(dá)到正常使用原生click事件的目的。代碼如下:

<meta name="viewport" content=" initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

所以,在iOS移動(dòng)端,如果想要實(shí)現(xiàn)真正的單擊事件而沒(méi)有300毫秒延遲問(wèn)題,就不能采用原生的click事件,可以通過(guò)touch(touchstart、touchmove和touchend)事件來(lái)模擬一次單擊操作。好在當(dāng)前業(yè)界已有比較流行的方案,例如Zepto.js中的tap事件和FastClick.js庫(kù)可用來(lái)解決這個(gè)問(wèn)題,在這里主要介紹一下FastClick.js庫(kù)。

FastClick.js是FT Labs團(tuán)隊(duì)結(jié)合touch事件專門為解決移動(dòng)端瀏覽器的300毫秒單擊延遲問(wèn)題所開(kāi)發(fā)的一個(gè)輕量級(jí)的庫(kù)。正常情況下,在移動(dòng)Web端,當(dāng)用戶單擊屏幕時(shí),會(huì)依次觸發(fā)touchstart、touchmove(0 次或多次)、touchend、click(原生)這些事件。touchmove事件只有當(dāng)手指在屏幕上移動(dòng)時(shí)才會(huì)觸發(fā)。Touchstart、touchmove或者touchend 事件的任意一個(gè)調(diào)用event.preventDefault()方法,都會(huì)直接阻止原生click事件的觸發(fā)。

FastClick的實(shí)現(xiàn)原理是在檢測(cè)到touchend事件觸發(fā)時(shí),把瀏覽器在300毫秒之后原生的click事件阻止掉,然后通過(guò)DOM自定義事件立即發(fā)出一個(gè)模擬的click事件,這樣就消除了300毫秒的延遲,提供了一個(gè)快速響應(yīng)的“單擊”事件。如下代碼演示了FastClick的使用。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  <title>FastClick.js</title>
  <script type="text/javascript" src="./fastclick.js"></script>
</head>
<body>
  <button id="click">點(diǎn)我</button>
  <script type="text/javascript">
    // 頁(yè)面加載完成后,使用FastClick,一般傳遞最外層的body元素即可
    document.addEventListener('DOMContentLoaded', function(){
        FastClick.attach(document.body);// 在實(shí)際的項(xiàng)目中,需判斷在iOS移動(dòng)端才需要此程序邏輯
    }, false);
    document.getElementById("click").addEventListener("click",function(){
        alert("單擊觸發(fā)! ");
    },false)
  </script>
</body>
</html>

需要注意的是,在不修改<meta>標(biāo)簽中的user-scalable屬性的情況下,300毫秒單擊延遲的問(wèn)題只會(huì)出現(xiàn)在iOS系統(tǒng)的瀏覽器中,并且解決方案只需要針對(duì)iOS端,上文也提到了這個(gè)問(wèn)題的產(chǎn)生是由于對(duì)user-scalable支持度存在Bug,之后蘋果公司也意識(shí)到了這個(gè)問(wèn)題的嚴(yán)重性,于是在iOS 9.3版本時(shí),提供了一個(gè)基于新的內(nèi)核WKWebView的瀏覽器,并將其應(yīng)用在Safari瀏覽器上,由此解決了這個(gè)問(wèn)題(存在300毫秒單擊延遲問(wèn)題的瀏覽器是UIWebView,這個(gè)內(nèi)核已經(jīng)不再維護(hù)了),并且后續(xù)使用iOS 9.3版本系統(tǒng)的瀏覽器在訪問(wèn)頁(yè)面時(shí),會(huì)默認(rèn)使用WKWebView瀏覽器。

至此,移動(dòng)Web端的300毫秒單擊延遲問(wèn)題得到了徹底的改善。

“單擊穿透”問(wèn)題

在移動(dòng)Web端,有一個(gè)很常見(jiàn)的應(yīng)用場(chǎng)景,單擊一個(gè)按鈕會(huì)出現(xiàn)一個(gè)蒙層,此蒙層是全屏遮蓋,并且有最高層級(jí),當(dāng)單擊蒙層時(shí),蒙層消失。此場(chǎng)景和交互操作看似并沒(méi)有什么問(wèn)題,但是假如頁(yè)面中有一個(gè)綁定了單擊事件的<div>元素被蒙層遮蓋,而單擊蒙層關(guān)閉時(shí)的位置剛好和該<div>元素重合,那么蒙層關(guān)閉后會(huì)同時(shí)觸發(fā)該<div>元素的單擊事件,對(duì)于用戶來(lái)說(shuō),這個(gè)操作并不是要單擊該<div>元素,這就是所謂的“單擊穿透”問(wèn)題,如圖。

出現(xiàn)“單擊穿透”問(wèn)題需要有個(gè)條件,即蒙層是通過(guò)綁定的touch事件來(lái)實(shí)現(xiàn)隱藏,而其遮蓋的<div>元素綁定的是原生click事件,這樣就形成了touch事件觸發(fā)之后,蒙層隱藏了,300毫秒后當(dāng)前這個(gè)觸摸點(diǎn)的click事件又觸發(fā)了,就形成“單擊穿透”。

移動(dòng)Web端的“單擊穿透”問(wèn)題出現(xiàn)的原因其實(shí)和300毫秒單擊延遲問(wèn)題脫不了關(guān)系,但是“單擊穿透”出現(xiàn)的場(chǎng)景比較單一,并且也比較好解決。

解決“單擊穿透”問(wèn)題可以從問(wèn)題出現(xiàn)的原因上來(lái)著手,主要有以下兩種解決方案:

  • 不要同時(shí)混用touch事件和click事件,要么給蒙層和<div>元素同時(shí)綁定touch事件,要么同時(shí)綁定click事件,在iOS 9.3版本之后,只用click事件即可,此方案體驗(yàn)最好。
  • 延遲蒙層消失的時(shí)間,例如在touch事件觸發(fā)后,在350毫秒后再讓蒙層消失,這樣后面的<div>元素就不會(huì)觸發(fā)click事件了,此方案會(huì)導(dǎo)致蒙層消失的響應(yīng)慢,體驗(yàn)差,并且有時(shí)會(huì)觸發(fā)兩次消失邏輯,故不推薦使用。

無(wú)論是300毫秒單擊延遲問(wèn)題,還是“單擊穿透”問(wèn)題,這些都是移動(dòng)Web端特有的問(wèn)題,也在一定程度上反映出移動(dòng)Web端環(huán)境的復(fù)雜性,需要注意支持度和兼容性問(wèn)題的地方很多,所以大家在進(jìn)行移動(dòng)Web端開(kāi)發(fā)時(shí),要有意識(shí)地去關(guān)注這些問(wèn)題。

以上就是移動(dòng)web開(kāi)發(fā)技能之touch事件詳解的詳細(xì)內(nèi)容,更多關(guān)于web移動(dòng)touch事件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • iOS中狀態(tài)欄的基本使用方法匯總

    iOS中狀態(tài)欄的基本使用方法匯總

    在iOS開(kāi)發(fā)過(guò)程中,經(jīng)常會(huì)設(shè)置狀態(tài)欄的樣式,所以下面這篇文章主要給大家介紹了關(guān)于iOS中狀態(tài)欄的基本使用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-07-07
  • 簡(jiǎn)單好用可任意定制的iOS Popover氣泡效果

    簡(jiǎn)單好用可任意定制的iOS Popover氣泡效果

    Popover(氣泡彈出框/彈出式氣泡/氣泡)是由一個(gè)矩形和三角箭頭組成的彈出窗口,箭頭指向的地方通常是導(dǎo)致Popover彈出的控件或區(qū)域。本文通過(guò)實(shí)例代碼給大家介紹了iOS Popover氣泡效果,需要的朋友參考下吧
    2017-12-12
  • iOS打電話、發(fā)短信、發(fā)郵件實(shí)例代碼

    iOS打電話、發(fā)短信、發(fā)郵件實(shí)例代碼

    這篇文章主要為大家詳細(xì)介紹了iOS打電話、發(fā)短信、發(fā)郵件實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • Drawer?Builder組件實(shí)現(xiàn)flutter側(cè)邊抽屜效果示例分析

    Drawer?Builder組件實(shí)現(xiàn)flutter側(cè)邊抽屜效果示例分析

    這篇文章主要為大家介紹了Drawer?Builder組件實(shí)現(xiàn)flutter側(cè)邊抽屜效果示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • IOS  手勢(shì)操作詳解及實(shí)例總結(jié)篇

    IOS 手勢(shì)操作詳解及實(shí)例總結(jié)篇

    這篇文章主要介紹了IOS 手勢(shì)操作詳解及實(shí)例總結(jié)篇的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • iOS 實(shí)現(xiàn)簡(jiǎn)單的加載等待動(dòng)畫示例(思路與實(shí)現(xiàn))

    iOS 實(shí)現(xiàn)簡(jiǎn)單的加載等待動(dòng)畫示例(思路與實(shí)現(xiàn))

    本篇文章主要介紹了iOS 實(shí)現(xiàn)簡(jiǎn)單的加載等待動(dòng)畫示例(思路與實(shí)現(xiàn)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • iOS創(chuàng)建對(duì)象的不同姿勢(shì)詳解

    iOS創(chuàng)建對(duì)象的不同姿勢(shì)詳解

    這篇文章主要介紹了iOS創(chuàng)建對(duì)象的不同姿勢(shì),文中介紹的很詳細(xì),對(duì)大家具有一定的參考價(jià)值,有需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-02-02
  • IOS中html5上傳圖片方向問(wèn)題解決方法

    IOS中html5上傳圖片方向問(wèn)題解決方法

    這篇文章主要介紹了IOS中html5上傳圖片方向問(wèn)題解決方法的相關(guān)資料,需要的朋友可以參考下
    2016-01-01
  • iOS中如何獲取某個(gè)視圖的截圖詳析

    iOS中如何獲取某個(gè)視圖的截圖詳析

    這篇文章主要給大家介紹了關(guān)于在iOS中如何獲取某個(gè)視圖的截圖的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)各位iOS開(kāi)發(fā)者們有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • iOS自定義鍵盤切換效果

    iOS自定義鍵盤切換效果

    這篇文章主要為大家詳細(xì)介紹了iOS自定義鍵盤切換效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-04-04

最新評(píng)論