天天看點

10-移動端開發教程-移動端事件

在前端的移動Web開發中,有一部分事件隻在移動端産生,如觸摸相關的事件。接下來給大家簡單總結一下移動端的事件。

由于移動端預設的布局視口寬度是980像素,是以網頁文字非常小,為了快速讓網頁還原到原來的大小,Safari最新引入了輕按兩下縮放功能:使用者輕按兩下手機頁面的時候,浏覽器會智能的縮放目前頁面到原始大小。

​輕按兩下縮放的原理就是,當使用者click一次之後,浏覽器會經過約300ms之後檢測是否再有一次click,如果有的話,就會縮放頁面。否則的話就是一個click事件。

由于輕按兩下縮放功能存在,click事件觸發就會有大約200~300ms的延遲。

由于輕按兩下縮放的存在,pc端的dblclick事件也失效了。

由于移動端裝置大都具備觸摸功能,是以移動端浏覽器都引入了觸摸(touch)事件。

touch相關的事件跟普通的其他dom事件一樣使用,可以直接用addEventListener來監聽和處理。

最基本的touch事件包括4個事件:

touchstart: 當在螢幕上按下手指時觸發

touchmove: 當在螢幕上移動手指時觸發

touchend: 當在螢幕上擡起手指時觸發

touchcancel 當一些更進階别的事件發生的時候(如電話接入或者彈出資訊)會取消目前的touch操作,即觸發touchcancel。一般會在touchcancel時暫停遊戲、存檔等操作。

在很多情況下,觸摸事件和滑鼠事件會同時被觸發(目的是讓沒有對觸摸裝置優化的代碼仍然可以在觸摸裝置上正常工作)。

因為輕按兩下縮放檢測的存在,在移動裝置螢幕上點選操作的事件執行順序:

touchstart(瞬間觸發) → touchend → click(200-300ms延遲)

如果你使用了觸摸事件,可以調用 event.preventDefault()來阻止滑鼠事件被觸發。

​ 當使用者手指觸摸到的觸摸屏的時候觸發。事件對象的 target 就是touch 發生位置的那個元素。

當使用者在觸摸屏上移動觸點(手指)的時候,觸發這個事件。一定是先要觸發touchstart事件,再有可能觸發 touchmove 事件。

​touchmove 事件的target 與最先觸發的 touchstart 的 target 保持一緻。touchmove事件和滑鼠的mousemove事件一樣都會多次重複調用,是以,事件處理時不能有太多耗時操作。不同的裝置,移動同樣的距離 touchmove 事件的觸發頻率是不同的。

注意: 即使手指移出了 原來的target 元素,則 touchmove 仍然會被一直觸發,而且 target 仍然是原來的 target 元素。

​ 當使用者的手指擡起的時候,會觸發 touchend 事件。如何使用者的手指從觸屏裝置的邊緣移出了觸屏裝置,也會觸發 touchend 事件。

touchend 事件的 target 也是與 touchstart 的 target 一緻,即使已經移出了元素。

一次完整的touch事件的觸發順序和過程

​ 當觸點由于某些原因被中斷時觸發。有幾種可能的原因如下(具體的原因根據不同的裝置和浏覽器有所不同):

由于某個事件取消了觸摸:例如觸摸過程被一個模态的彈出框打斷。

觸點離開了文檔視窗,而進入了浏覽器的界面元素、插件或者其他外部内容區域。

當使用者産生的觸點個數超過了裝置支援的個數,進而導緻 TouchList 中最早的 Touch對象被取消

touchcancel 事件一般用于儲存現場資料。比如:正在玩遊戲,如果發生了 。touchcancel 事件,則應該把遊戲目前狀态相關的一些資料儲存起來。

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

屬性清單:

​ 一個<code>TouchList</code>代表一個觸摸螢幕上所有觸點的清單。

​ 舉例來講, 如果一個使用者用三根手指接觸螢幕(或者觸控闆), 與之相關的<code>TouchList</code> 對于每根手指都會生成一個 <code>Touch</code>對象, 共計 3 個.

隻讀屬性:<code>length</code>

傳回這個<code>TouchList</code>中<code>Touch</code>對的個數。(就是有幾個手指接觸到了螢幕)

方法:<code>item(index)</code>

傳回<code>TouchList</code>中指定索引的<code>Touch</code>對象。

測試多個手機觸摸螢幕:

操作:

放1個手指在div上

先放1個手指在其他地方,然後再放1個手指在<code>div</code>上

先放1個手指在其他地方,然後再逐漸放2個手指在<code>div</code>上

​ <code>Touch</code>表示使用者和觸摸裝置之間接觸時單獨的互動點(<code>a single point of contact</code>)。​ 這個互動點通常是一個手指或者觸摸筆,​ 觸摸裝置通常是觸摸屏或者觸摸闆。

基本屬性清單(都是隻讀):

編号

屬性名

屬性說明

1.

<code>identifier</code>

表示每 1 個 <code>Touch</code> 對象 的獨一無二的 <code>identifier</code>。有了這個 <code>identifier</code> 可以確定你總能追蹤到這個 <code>Touch</code>對象。

2.

<code>screenX</code>

觸摸點相對于螢幕左邊緣的 <code>x</code> 坐标。

3.

<code>scre</code>enY

觸摸點相對于螢幕上邊緣的 <code>y</code> 坐标。

4.

<code>clientX</code>

觸摸點相對于浏覽器的 <code>viewport</code>左邊緣的 <code>x</code> 坐标。不會包括左邊的滾動距離。

5.

<code>clientY</code>

觸摸點相對于浏覽器的 <code>viewport</code>上邊緣的 <code>y</code> 坐标。不會包括上邊的滾動距離。

6.

<code>pageX</code>

觸摸點相對于 <code>document</code>的左邊緣的 <code>x</code> 坐标。 與 <code>clientX</code> 不同的是,他包括左邊滾動的距離,如果有的話。

7.

<code>pageY</code>

觸摸點相對于 <code>document</code>的左邊緣的 <code>y</code> 坐标。 與 <code>clientY</code> 不同的是,他包括上邊滾動的距離,如果有的話。

8.

<code>target</code>

總是表示 手指最開始放在觸摸裝置上的觸發點所在位置的 <code>element</code>。 即使已經移出了元素甚至移出了<code>document</code>, 他表示的<code>element</code>仍然不變

案例:

沒有左右滾動:

左右滾動:<code>pageX</code> 明顯大于 <code>clientX</code>

由于點選事件經常使用,如果用click會有延遲問題,一般我們會用touch事件模拟移動端的點選事件, 以下是封裝的幾個事件,僅供參考。

手勢相關的事件一般就是tap類(觸屏)和滑動(swipe)事件兩類。都是基于原生的touchstart、touchmove、touchend事件,封裝成不同的手勢類型自定義事件。

觸碰事件,我目前還不知道它和touch的差別,一般用于代替click事件,有tap longTap singleTap doubleTap四種之分。

tap: 手指碰一下螢幕會觸發

longTap: 手指長按螢幕會觸發

singleTap: 手指碰一下螢幕會觸發

doubleTap: 手指輕按兩下螢幕會觸發

滑動事件,有swipe swipeLeft swipeRight swipeUp swipeDown 五種之分。

swipe:手指在螢幕上滑動時會觸發

swipeLeft:手指在螢幕上向左滑動時會觸發

swipeRight:手指在螢幕上向右滑動時會觸發

swipeUp:手指在螢幕上向上滑動時會觸發

swipeDown:手指在螢幕上向下滑動時會觸發

Zepto.js的touch子產品中封裝了手勢相關的代碼。封裝了再觸摸裝置上觸發tap– 和 swipe– 相關事件,也适用于所有的<code>touch</code>(iOS, Android)和<code>pointer</code>事件(Windows Phone)。

觸屏事件:tap、singleTap、doubleTap、longTap(&gt;750ms)

滑動事件:swipe、swipeLeft,、swipeRight,、swipeUp,、swipeDown

<a href="https://link.jianshu.com/?t=https%3A%2F%2Fgithub.com%2FClouda-team%2Ftouchjs" target="_blank">百度雲的touch.js</a>

<a href="https://link.jianshu.com/?t=https%3A%2F%2Fgithub.com%2Fhammerjs%2Fhammer.js" target="_blank">hammer.js</a>

如果某個傳回按鈕的位置,恰好在要傳回的這個頁面的帶有href屬性的a标簽的範圍内,在點選傳回按鈕後,頁面快速切換到有a标簽的頁面,300ms後觸發了click事件,進而觸發了a标簽的意外跳轉,這個就是典型的點選穿透問題。罪魁禍首其實就是a标簽跳轉預設是click事件觸發,而移動端的touch事件觸發之後,依然會在300ms後觸發click事件。

解決辦法:

1.就是阻止觸發touch事件完成後的click事件。

2.不要混用touch和click事件。顯然不可能都綁定click事件,因為要解決300ms延遲問題(除了fastclick),那麼隻能都綁定touch事件,這樣click事件永遠不會被觸發。

注意:zepto并沒有阻止click事件,是以使用zepto的tap事件依然會導緻點選穿透問題,你需要手動添加 e.preventDefault() 來阻止click事件。

參考文章:

<a href="https://link.jianshu.com/?t=http%3A%2F%2Fblog.csdn.net%2Fu012468376%2Farticle%2Fdetails%2F72808761" target="_blank">移動端web開發---Touch事件詳解</a>

<a href="https://link.jianshu.com/?t=https%3A%2F%2Fdeveloper.mozilla.org%2Fzh-CN%2Fdocs%2FWeb%2FAPI%2FTouchEvent" target="_blank">MDN:TouchEvent</a>

<a href="https://link.jianshu.com/?t=http%3A%2F%2Fwww.cnblogs.com%2Fimwtr%2Fp%2F5882166.html" target="_blank">移動端前端常見的觸摸相關事件touch、tap、swipe等整理</a>

繼續閱讀