亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

概述

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

touch事件

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

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

touch事件分類

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

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

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

其中的touchstart、touchmove和touchend是最常用的3個(gè)事件,其中touchstart最先觸發(fā),touchend結(jié)束時(shí)觸發(fā),而touchmove是否觸發(fā)取決于手指是否在觸摸屏上移動(dòng)。下面用代碼來感受一下這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("開始觸摸");
    });
    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è)簡單的觸摸操作是如何完成的。

touch事件對(duì)象

對(duì)于touch事件,每一次觸發(fā)都可以得到一個(gè)事件對(duì)象,在JavaScript中這個(gè)對(duì)象叫作TouchEvent,利用TouchEvent可以獲取touch事件觸發(fā)時(shí)的坐標(biāo)、元素以及到底有幾個(gè)手指觸發(fā)等,下面就來了解一下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)前頁面(屏幕)上所有的觸摸點(diǎn)。
  • targetTouches:當(dāng)前綁定事件的元素上的觸摸點(diǎn)。
  • changedTouches:當(dāng)前屏幕上剛剛接觸的手指或者離開的手指的觸摸點(diǎn)。

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

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

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

外層的線框代表頁面,里面的一個(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)手指都離開屏幕之后,touches和targetTouches中將不會(huì)再有值,changedTouches還會(huì)有一個(gè)值,此值為最后一個(gè)離開屏幕的手指的接觸點(diǎn)。這就是touches、targetTouches和changedTouches這3個(gè)屬性對(duì)于單指觸摸的場景和多指觸摸的場景下的區(qū)別,總結(jié)如下:

單指觸摸的場景:

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

多指觸摸的場景:

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

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

對(duì)于涵蓋觸摸點(diǎn)的集合數(shù)組TouchList而言,里面每個(gè)元素都是一個(gè)touch對(duì)象,通過這個(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è)頁面內(nèi)容區(qū)域的位置坐標(biāo),當(dāng)頁面過長時(shí),包括滾動(dòng)隱藏的部分內(nèi)容,以頁面完整內(nèi)容區(qū)域的左上角為原點(diǎn)。
  • clientX/Y:觸摸位置相當(dāng)于瀏覽器視區(qū)(屏幕)區(qū)域的位置坐標(biāo),以相對(duì)于頁面的可見部分內(nèi)容區(qū)域的左上角為原點(diǎn)。

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

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

在了解了touch事件之后,我們知道移動(dòng)Web端的單擊事件完全可以由touchstart、touchmove和touchend來組合實(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),長按等)就使用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è)問題:當(dāng)時(shí)的網(wǎng)站都是為大屏幕設(shè)備所設(shè)計(jì)的,于是提出了視區(qū)(Viewport)的概念,其中一項(xiàng)即是用戶在瀏覽網(wǎng)頁時(shí),可以在頁面的任何地方通過雙擊操作將頁面放大(Double Tap to Zoom)。這個(gè)交互功能提升了用戶瀏覽網(wǎng)頁時(shí)的體驗(yàn),于是Android和iOS的移動(dòng)端瀏覽器紛紛支持了這個(gè)功能,但是對(duì)于雙擊這個(gè)操作而言,其實(shí)是包括了兩次單擊操作,當(dāng)?shù)谝淮螁螕敉瓿珊?,系統(tǒng)需要有一段時(shí)間來監(jiān)聽是否有第二次單擊,如果有則表明此次操作是一個(gè)雙擊操作,而這段時(shí)間間隔大概有300毫秒(ms)。

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

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

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

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

FastClick.js是FT Labs團(tuán)隊(duì)結(jié)合touch事件專門為解決移動(dòng)端瀏覽器的300毫秒單擊延遲問題所開發(fā)的一個(gè)輕量級(jí)的庫。正常情況下,在移動(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事件阻止掉,然后通過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">
    // 頁面加載完成后,使用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毫秒單擊延遲的問題只會(huì)出現(xiàn)在iOS系統(tǒng)的瀏覽器中,并且解決方案只需要針對(duì)iOS端,上文也提到了這個(gè)問題的產(chǎn)生是由于對(duì)user-scalable支持度存在Bug,之后蘋果公司也意識(shí)到了這個(gè)問題的嚴(yán)重性,于是在iOS 9.3版本時(shí),提供了一個(gè)基于新的內(nèi)核WKWebView的瀏覽器,并將其應(yīng)用在Safari瀏覽器上,由此解決了這個(gè)問題(存在300毫秒單擊延遲問題的瀏覽器是UIWebView,這個(gè)內(nèi)核已經(jīng)不再維護(hù)了),并且后續(xù)使用iOS 9.3版本系統(tǒng)的瀏覽器在訪問頁面時(shí),會(huì)默認(rèn)使用WKWebView瀏覽器。

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

“單擊穿透”問題

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

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

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

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

  • 不要同時(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ā)兩次消失邏輯,故不推薦使用。

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

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

    簡單好用可任意定制的iOS Popover氣泡效果

    Popover(氣泡彈出框/彈出式氣泡/氣泡)是由一個(gè)矩形和三角箭頭組成的彈出窗口,箭頭指向的地方通常是導(dǎo)致Popover彈出的控件或區(qū)域。本文通過實(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)簡單的加載等待動(dòng)畫示例(思路與實(shí)現(xiàn))

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

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

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

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

    IOS中html5上傳圖片方向問題解決方法

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

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

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

    iOS自定義鍵盤切換效果

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

最新評(píng)論