最近看了一本《移動Web手冊》的書,奇舞團翻譯的,很是不錯。我的以爲在進入移動端的時候最早應該瞭解移動端新的交互模式:觸摸。爲何這樣說呢?在PC端,咱們大多數的交互都是經過鼠標來實現,在開發過程當中,對鼠標事件的處理也很是多,經過以前在移動端的開發經驗,在移動端的交互也避免不了常常與觸摸打交道,因此咱們有必要單獨學習一下它。javascript
(1) 連續性css
觸摸事件是不連續的,鼠標事件是連續的。html
操做順序:A -> B -> Cjava
在鼠標上:鼠標點擊A -> 劃過B -> 點擊C瀏覽器
在觸摸上:手指觸摸A -> 跨過B -> 觸摸Cdom
(2) 下一步預期的操做學習
在鼠標上:移入元素 -> 點擊鼠標左鍵 -> 觸發單擊 -> 在有效時間內點擊第二次 -> 觸發雙擊測試
在觸摸上,可能有如下幾種狀況:網站
其實做者認爲鼠標事件在用戶點擊的時候就可以判斷行爲,其實我以爲若是是雙擊事件的狀況下,瀏覽器也須要等待一段時間纔可以作出反應。這個能夠查閱一下google。google
(3) 等價事件
在瞭解兩種不一樣的交互模式的基礎上,咱們再來進行單個的分析。其實我以爲學習同樣東西,最根本的仍是摸清原理部分,就可以很快的Get它了,固然,編碼量不夠的狀況下也許仍是須要慢慢來,掌握得更加紮實。
(1) 事件種類
其實從命名上就能很清楚的明白他們是幹嗎的,固然,有一個比較特殊:touchcancel事件,可能會不太好理解,在最初的學習中能夠忽略它,這裏作一個簡單的介紹:
touchcancel 在系統發生中斷的時候會觸發,這樣說很抽象,咱們來舉一個栗子,好比你正在玩遊戲,觸摸的時候,忽然手機來了一條短信,這個時候短信通知這個更高級的事件中斷了觸摸操做,touchcancel事件就觸發了。在這個時候遊戲開發中,會使用它來進行暫停遊戲等操做。
因爲touchcancel觸發的時機很差掌控,因此通常狀況下咱們會採用下面的方式來處理touchcancel,維護咱們的代碼邏輯,固然這個要看業務場景。
dom.addEventListener('touchcancel', function(e){ e.preventDefault(); }, false);
(2) 觸發時機
介紹完了事件的種類,咱們來對每一種事件都進行代碼級別的測試,看一看是否跟它說的前後順序同樣,這裏我將引入鼠標事件一塊兒測試,由於有一些區別性的東西哦。
咱們先看一下測試結果:(iOS 8.3 Safari)
A.直接觸摸空白部分,而後直接離開
B.在空白區域觸摸並滑動,而後離開
C.點擊界面中的按鈕,未阻止冒泡
D.點擊界面中一塊區域,阻止冒泡
E.長按屏幕空白部分,出現選中效果,而後馬上離開屏幕
結果很明瞭,就不須要總結了,下面咱們看一下測試的代碼:
DOM
<div> <button class="btn">這裏是一個按鈕</button> <span class="area">這裏是一塊可點擊區域</span> <p class="info"></p> </div>
JavaScript
;(function () { var doc = document; var info = doc.querySelector('.info'); var btn = doc.querySelector('.btn'); var area = doc.querySelector('.area'); doc.ontouchstart = function (e) { info.innerHTML += ', '+ e.type; } doc.ontouchmove = function (e) { info.innerHTML += ', '+ e.type; } doc.ontouchend = function (e) { info.innerHTML += ', '+ e.type; } doc.ontouchcancel = function (e) { info.innerHTML += ', '+ e.type; } doc.onmouseover = function (e) { info.innerHTML += ', '+ e.type; } doc.onmousemove = function (e) { info.innerHTML += ', '+ e.type; } doc.onmousedown = function (e) { info.innerHTML += ', '+ e.type; } doc.onmouseup = function (e) { info.innerHTML += ', '+ e.type; } doc.onmouseleave = function (e) { info.innerHTML += ', '+ e.type; } doc.onclick = function (e) { info.innerHTML += ', document: '+ e.type; } btn.onclick = function (e) { info.innerHTML += ', button: '+ e.type; } area.onclick = function (e) { e.stopPropagation(); info.innerHTML += ', area: '+ e.type; } })();
CSS
.btn { width: 100%; height: 60px; line-height: 60px; font-size: 16px; border: none; color: #fff; text-align: center; background: #2A3846; } .area { display: block; width: 100%; height: 60px; line-height: 60px; color: #fff; text-align: center; background: #2A3846; margin-top: 20px; }
爲了避免干擾直接知識的理解,以前沒有說不一樣meta頭的事情,以及Safari與UC瀏覽器之間的差別。畢竟要接地氣嘛,UC仍是要測試一下的。
狀況一
<meta name="viewport" content="width=device-width">
行爲:「觸摸空白區域,馬上離開時候的現象」
現象:
Safari:touchstart與touchend事件觸發後,延遲一段時間,觸發mouse以及click事件;
UC:只觸發了touchstart與touchend事件,並沒有觸發mouse和click事件。
行爲:「點擊頁面的按鈕(或者元素區域),馬上離開時候的現象」
現象:
Safari:touchstart與touchend事件觸發後,延遲一段時間,觸發mouse以及click事件,不過click觸發是從按鈕到document的順序;
UC:與Safari中表現一致。
總結:
狀況二
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
先不考慮這樣寫不符合單一變量測試原則,國內移動網站大多都是這樣的meta頭,固然,我有測試過,只要帶有user-scalable一項就可以知足下面的實驗。
不過下面的實驗咱們排除「點擊空白區域這種狀況」,由於這document綁定事件確實有差別,咱們只測試「點擊按鈕」這一種行爲。
行爲:「點擊頁面的按鈕(或者元素區域),馬上離開時候的現象」
現象:
Safari:touchstart與touchend事件觸發後,延遲一段時間,觸發mouse以及click事件,不過click觸發是從按鈕到document的順序;
UC:touchstart、touchend、mouse、click前後順序不變,可是幾乎是同時觸發,沒有發生延遲。
總結:
在這種狀況下,Safari依然存在click事件延遲,UC不存在延遲。
好吧,我認可這樣實驗有點枯燥,可是必須得這樣才能弄明白到底怎麼了,究竟是怎麼了。。。
Tip:這裏讚美一下Safari,它可以很好的監聽touchmove事件,幾乎和手指移動的速度是同樣的,UC和Chrome表現均是手指移動一段事件後,再從事件棧裏面拋出觸發,固然,Chrome觸發的速度比UC好。尚未實際例子測試,不知是否會有影響,你們能夠測試了給一下結果。
發現總結成博文好慢,先不寫了,睡覺,接下來有時間將總結如下內容: