從觸摸開始

1. 前言

最近看了一本《移動Web手冊》的書,奇舞團翻譯的,很是不錯。我的以爲在進入移動端的時候最早應該瞭解移動端新的交互模式:觸摸。爲何這樣說呢?在PC端,咱們大多數的交互都是經過鼠標來實現,在開發過程當中,對鼠標事件的處理也很是多,經過以前在移動端的開發經驗,在移動端的交互也避免不了常常與觸摸打交道,因此咱們有必要單獨學習一下它。javascript

2. 觸摸、鼠標交互模式

(1) 連續性css

觸摸事件是不連續的,鼠標事件是連續的。html

連續性

操做順序:A -> B -> Cjava

在鼠標上:鼠標點擊A -> 劃過B -> 點擊C瀏覽器

在觸摸上:手指觸摸A -> 跨過B -> 觸摸Cdom

(2) 下一步預期的操做學習

在鼠標上:移入元素 -> 點擊鼠標左鍵 -> 觸發單擊 -> 在有效時間內點擊第二次 -> 觸發雙擊測試

鼠標

在觸摸上,可能有如下幾種狀況:網站

  1. 手指觸摸屏幕 -> 輕觸
  2. 手指觸摸屏幕 -> 雙觸
  3. 手指觸摸屏幕 -> 滑動
  4. 手指觸摸屏幕 -> 縮放

觸摸

其實做者認爲鼠標事件在用戶點擊的時候就可以判斷行爲,其實我以爲若是是雙擊事件的狀況下,瀏覽器也須要等待一段時間纔可以作出反應。這個能夠查閱一下google。google

(3) 等價事件

等價事件

3. 單說觸摸事件

在瞭解兩種不一樣的交互模式的基礎上,咱們再來進行單個的分析。其實我以爲學習同樣東西,最根本的仍是摸清原理部分,就可以很快的Get它了,固然,編碼量不夠的狀況下也許仍是須要慢慢來,掌握得更加紮實。

(1) 事件種類

  • touchstart: 手指觸摸屏幕的瞬間
  • touchmove: 手指在屏幕上移動的時候
  • touchend: 手指離開屏幕的時候
  • touchcancel

其實從命名上就能很清楚的明白他們是幹嗎的,固然,有一個比較特殊: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中表現一致。

總結:

  • 若是沒有禁止縮放,Safari和UC中的點擊事件均有延遲現象;
  • 在document上綁定事件,與其餘元素上綁定事件上述兩個瀏覽器之間存在差別。

狀況二

<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好。尚未實際例子測試,不知是否會有影響,你們能夠測試了給一下結果。

發現總結成博文好慢,先不寫了,睡覺,接下來有時間將總結如下內容:

  • 事件級聯深刻解析
  • 300ms延遲的產生原理與解決方案
  • 事件默認事件、事件冒泡在移動端的影響
  • 觸摸事件怎麼玩?
  • 觸摸中的搖曳與HTML5中的搖曳栗子
  • 觸摸中無限滾動的栗子
  • W3C中的Touch Events
  • 將來的Pointer Events
相關文章
相關標籤/搜索