摘要:指針事件給用戶代理帶來(lái)靈活性,給一個(gè)事件系統(tǒng)提供豐富的輸入機(jī)制。就像蘋(píng)果和谷歌現(xiàn)在就沒(méi)有打算來(lái)實(shí)現(xiàn)指針事件。谷歌的這個(gè)決定并不是他們最終的決定,但是目前在指針事件上沒(méi)有活躍的工作。
原文地址:http://tw93.github.io/2015-03-30/Browser-input-Events.html
響應(yīng)用戶的輸入可以說(shuō)是我們做界面開(kāi)發(fā)的核心。為了構(gòu)建可響應(yīng)的Web產(chǎn)品,理解觸摸、鼠標(biāo)、指針、鍵盤(pán)操作和瀏覽器的工作原理是解決問(wèn)題的關(guān)鍵。你可能在手機(jī)瀏覽器中經(jīng)歷過(guò)300-millisecond delay(300 ms延遲)或者wrestled with touchmove versus scrolling(觸摸滾動(dòng)導(dǎo)致頁(yè)面卡頓)。
在本文中,我們將介紹事件級(jí)聯(lián)和使用這些知識(shí)來(lái)實(shí)現(xiàn)演示一個(gè)tap點(diǎn)擊事件,支持多種輸入方法但是又沒(méi)有違反像Opera Mini這一類的代理瀏覽器規(guī)則。
注:tap也翻譯為點(diǎn)擊,tap和click都是在點(diǎn)擊時(shí)候觸發(fā),但在手機(jī)Web端click會(huì)有200~300ms延遲,為了避免歧義,下文將” tap event“翻譯成“tap點(diǎn)擊事件“
概況目前被用于與Web交互的3種主要的交互方式是:數(shù)字光標(biāo)(鼠標(biāo))、觸覺(jué)(直接觸摸或者手寫(xiě)筆)、鍵盤(pán)。在JavaScript中我們可以通過(guò)觸摸事件,鼠標(biāo)事件,指針事件和鍵盤(pán)事件來(lái)使用它們。在這篇文章中我們主要討論觸摸和基于鼠標(biāo)的交互,雖然這里有鍵盤(pán)事件已經(jīng)形成標(biāo)準(zhǔn),如click和submit事件。
你很有可能已經(jīng)實(shí)現(xiàn)過(guò)鼠標(biāo)和觸摸事件的處理程序,在過(guò)去我們推薦的做法是這樣:
javascript/** DO NOT EVER DO THIS! */ $("a", ("ontouchstart" in window)?"touchend":"click",handler);
微軟已經(jīng)負(fù)責(zé)創(chuàng)建了一個(gè)更好的,更有前途的“指針事件”的事件模型規(guī)范。指針事件是一個(gè)抽象的輸入機(jī)制,現(xiàn)在是W3C推薦標(biāo)準(zhǔn)。指針事件給用戶代理(UA)帶來(lái)靈活性,給一個(gè)事件系統(tǒng)提供豐富的輸入機(jī)制。鼠標(biāo)、觸摸、手寫(xiě)筆是今天很容易想到的輸入方式,但實(shí)現(xiàn)延伸到myo(肌)和Ring(環(huán))也是可實(shí)現(xiàn)的。雖然Web開(kāi)發(fā)者對(duì)這些似乎很興奮,但并不是所有的瀏覽器開(kāi)發(fā)者也會(huì)這樣以為。就像蘋(píng)果和谷歌現(xiàn)在就沒(méi)有打算來(lái)實(shí)現(xiàn)指針事件。
谷歌的這個(gè)決定并不是他們最終的決定,但是目前在指針事件上沒(méi)有活躍的工作。我們通過(guò)polyfills輸入和使用指針事件和替代解決方案將成為等式的一部分,可能最終起決定作用。蘋(píng)果在2012年發(fā)表申明反對(duì)指針事件,我現(xiàn)在沒(méi)有從Safari的工程師那里得到任何公眾回應(yīng)。
事件級(jí)聯(lián)當(dāng)用戶在移動(dòng)設(shè)備上面tap點(diǎn)擊一個(gè)元素時(shí),瀏覽器會(huì)觸發(fā)一系列事件:
touchstart → touchend → mouseover → mousemove → mousedown → mouseup → click
這是由于Web的向后兼容性,指針事件采取的一種可替代方案來(lái)觸發(fā)事件內(nèi)聯(lián)的兼容性:
mousemove → pointerover → mouseover → pointerdown → mousedown → gotpointercapture → pointerup → mouseup → lostpointercapture → pointerout → mouseout → focus → click
事件規(guī)范允許用戶代理們用不同的方式來(lái)實(shí)現(xiàn)兼容性的事件,Patrick Lauke和Peter-Paul Koch維護(hù)著關(guān)于這一主題的廣泛的參考材料(資源鏈接位于文章底部)。
以下圖片顯示下列行為的事件串:
首次tap點(diǎn)擊一個(gè)元素
第二次tap點(diǎn)擊一個(gè)元素
tap點(diǎn)擊關(guān)閉元素
請(qǐng)注意:為了適應(yīng)這個(gè)棧這個(gè)事件棧故意忽略了focus和blur事件。
在IOS設(shè)備上的tap點(diǎn)擊一個(gè)元素兩次和松開(kāi)的事件級(jí)聯(lián)
在 Android 4.4 設(shè)備上的tap點(diǎn)擊一個(gè)元素兩次和松開(kāi)的事件級(jí)聯(lián)
在Internet Explorer 11(在兼容的觸摸事件實(shí)現(xiàn))上tap點(diǎn)擊元素兩次然后松開(kāi)的事件級(jí)聯(lián)
應(yīng)用事件級(jí)聯(lián)由于瀏覽器工程師的工作,大多數(shù)現(xiàn)在建成的桌面網(wǎng)站“只是可以工作而已”。盡管級(jí)聯(lián)看起來(lái)有點(diǎn)粗糙,但建立鼠標(biāo)事件是我們以前通常工作的保守做法。
當(dāng)然,300ms的延遲問(wèn)題比起在滾動(dòng)和touchmove和pointermove事件相互作用,還有瀏覽器渲染問(wèn)題這些額外的問(wèn)題更加臭名昭著。避免300 ms的延遲很容易,如果:
我們只為現(xiàn)代的Android和桌面端的Chrome優(yōu)化,通過(guò)使用來(lái)啟動(dòng)禁用延遲這一功能。
我們只為IOS設(shè)備優(yōu)化,用戶有一個(gè)明確的點(diǎn)擊,不是那種快速的點(diǎn)擊或者長(zhǎng)按,僅僅是一個(gè)元素良好的、正常的、明確的點(diǎn)擊。
如果我們的目標(biāo)是建立一個(gè)能在用戶體驗(yàn)和本地應(yīng)用媲美的Web應(yīng)用,那么我們需要減少交互響應(yīng)的延遲。為了達(dá)到這個(gè)目標(biāo),我們需要在原始事件(如down,move,up)上創(chuàng)建我們屬于自己的復(fù)合事件(click,double-click),當(dāng)然我們還需要對(duì)本地事件的回退處理提供廣泛和可行的支持。
做這些需要不少的代碼和知識(shí)。為了避免在瀏覽器中的300ms延遲,我們需要處理全部生命周期內(nèi)的自我交互。對(duì)于一個(gè)給定{類型}的down事件,我們需要綁定所有必需的事件來(lái)完成這個(gè)功能,當(dāng)交互已經(jīng)完成后,我們需要清理自己解綁的起始事件。
網(wǎng)站開(kāi)發(fā)人員,你是唯一一個(gè)知道頁(yè)面是否應(yīng)該放大或另一個(gè)雙擊事件是否必須等待的人。如果只有你需要回調(diào)推遲你應(yīng)該允許一個(gè)預(yù)定的動(dòng)作來(lái)延遲。
在接下來(lái)鏈接中,你會(huì)發(fā)現(xiàn)一個(gè)小的、相互間無(wú)依賴的tap事件Demo來(lái)創(chuàng)造一個(gè)多輸入、低延遲的tap點(diǎn)擊事件。Polymer-gestures是一個(gè)為tap點(diǎn)擊和其他事件生產(chǎn)開(kāi)發(fā)的庫(kù)。盡管是這個(gè)名字有Polymer,但是它是不依賴Polymer庫(kù)而且很容易被隔離。
明確的說(shuō),實(shí)施這個(gè)從一開(kāi)始來(lái)說(shuō)就是一個(gè)壞主意,以下這些應(yīng)該僅僅用于教育而不是用于生產(chǎn)環(huán)境。用于生產(chǎn)環(huán)境的庫(kù)已經(jīng)存在,例如: FastClick,polymer-gestures和Hammer.js。
Demo:The tap event
Code:taps.js
重要部分在所有開(kāi)始的地方綁定你的初始事件,這下面處理多輸入的模式是被認(rèn)為一種保險(xiǎn)的方式。
javascript/** * If there are pointer events, let the platform handle the input * mechanism abstraction. If not, then it’s on you to handle * between mouse and touch events. */ if (hasPointer) { tappable.addEventListener(POINTER_DOWN, tapStart, false); clickable.addEventListener(POINTER_DOWN, clickStart, false); } else { tappable.addEventListener("mousedown", tapStart, false); clickable.addEventListener("mousedown", clickStart, false); if (hasTouch) { tappable.addEventListener("touchstart", tapStart, false); clickable.addEventListener("touchstart", clickStart, false); } } clickable.addEventListener("click", clickEnd, false);
綁定touch事件需要和渲染性能妥協(xié),即使它們沒(méi)有做任何事,但為了減少這種影響,通常推薦在處理程序開(kāi)始時(shí)候綁定跟蹤事件。別忘了在完成你的事件處理后要清理自己的環(huán)境和解綁跟蹤事件。
javascript/** * On tapStart we want to bind our move and end events to detect * whether this is a “tap” action. * @param {Event} event the browser event object */ function tapStart(event) { // bind tracking events. “bindEventsFor” is a helper that automatically // binds the appropriate pointer, touch or mouse events based on our // current event type. Additionally, it saves the event target to give // us similar behavior to pointer events’ “setPointerCapture” method. bindEventsFor(event.type, event.target); if (typeof event.setPointerCapture === "function") { event.currentTarget.setPointerCapture(event.pointerId); } // prevent the cascade event.preventDefault(); // start our profiler to track time between events set(event, "tapStart", Date.now()); } /** * tapEnd. Our work here is done. Let’s clean up our tracking events. * @param {Element} target the html element * @param {Event} event the browser event object */ function tapEnd(target, event) { unbindEventsFor(event.type, target); var _id = idFor(event); log("Tap", diff(get(_id, "tapStart"), Date.now())); setTimeout(function() { delete events[_id]; });
剩下的這些代碼應(yīng)該能夠很好的自我解釋,事實(shí)上,它有很多簿記,實(shí)現(xiàn)自定義手勢(shì)要求你用瀏覽器事件系統(tǒng)來(lái)緊密合作。為了挽救你的受傷和心痛,不要在你自己的代碼庫(kù)里做事情。相反你應(yīng)該建立或使用一個(gè)強(qiáng)大的抽象,例如Hammer.js,jQuery polyfill的Pointer Events或者polymer-gestures。
總結(jié)一些曾經(jīng)很清楚的事件現(xiàn)在卻是有歧義的,以前click事件用來(lái)指有且只有一件事,但是現(xiàn)在在觸摸屏上面需要辨別是雙擊、滾動(dòng)或者其他操作系統(tǒng)的手勢(shì)。
好消息是,我們現(xiàn)在明白了很多用戶的操作習(xí)慣和瀏覽器的響應(yīng)之間的事件級(jí)聯(lián)和相互作用,通過(guò)在工作中認(rèn)識(shí)的原語(yǔ),我們自己能夠在我們的項(xiàng)目中為我們的用戶和Web的未來(lái)做出更好的決策。
你在構(gòu)建多設(shè)備的網(wǎng)站時(shí),有遇到什么意想不到的問(wèn)題?你采取什么樣的方法來(lái)解決Web上眾多的交互模式?
額外的資源“Pointer Events Finalized, But Apple’s Lack of Support Still a Deal Breaker,”P(pán)eter Bright
Getting Touchy: An Introduction to Touch and Pointer Events,包括slides和talk Patrick E. Lauke
“Apple’s Web?” by Tim Kadlec
“Avoiding the 300ms Click Delay, Accessibly,” Tim Kadlec
“Touch taple,” Peter-Paul Koch
“Making the Web ‘Just Work’ With Any Input: Mouse, Touch, and Pointer Events,” Jacob Rossi
FastClick library
Hammer.js
polymer-gestures
Pointer EventsjQuery polyfill
“Implement Custom Gestures,” Google Developers
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/85613.html
摘要:從現(xiàn)狀談及性能優(yōu)化原文出處性能優(yōu)化指南如今網(wǎng)絡(luò)發(fā)展迅猛,這對(duì)我們構(gòu)建的互聯(lián)網(wǎng)平臺(tái)要求也更高。這就說(shuō)明,我們?cè)陂_(kāi)發(fā)時(shí),并沒(méi)有站在用戶的角度上換位思考,更別談性能優(yōu)化。因此,我們可通過(guò)區(qū)分關(guān)鍵資源并調(diào)整加載的優(yōu)先級(jí)來(lái)實(shí)現(xiàn)性能優(yōu)化。 從web現(xiàn)狀談及性能優(yōu)化 原文出處:《Karolina Szczur: The State of the Web》 性能優(yōu)化指南The Internet is ...
摘要:從現(xiàn)狀談及性能優(yōu)化原文出處性能優(yōu)化指南如今網(wǎng)絡(luò)發(fā)展迅猛,這對(duì)我們構(gòu)建的互聯(lián)網(wǎng)平臺(tái)要求也更高。這就說(shuō)明,我們?cè)陂_(kāi)發(fā)時(shí),并沒(méi)有站在用戶的角度上換位思考,更別談性能優(yōu)化。因此,我們可通過(guò)區(qū)分關(guān)鍵資源并調(diào)整加載的優(yōu)先級(jí)來(lái)實(shí)現(xiàn)性能優(yōu)化。 從web現(xiàn)狀談及性能優(yōu)化 原文出處:《Karolina Szczur: The State of the Web》 性能優(yōu)化指南The Internet is ...
摘要:從現(xiàn)狀談及性能優(yōu)化原文出處性能優(yōu)化指南如今網(wǎng)絡(luò)發(fā)展迅猛,這對(duì)我們構(gòu)建的互聯(lián)網(wǎng)平臺(tái)要求也更高。這就說(shuō)明,我們?cè)陂_(kāi)發(fā)時(shí),并沒(méi)有站在用戶的角度上換位思考,更別談性能優(yōu)化。因此,我們可通過(guò)區(qū)分關(guān)鍵資源并調(diào)整加載的優(yōu)先級(jí)來(lái)實(shí)現(xiàn)性能優(yōu)化。 從web現(xiàn)狀談及性能優(yōu)化 原文出處:《Karolina Szczur: The State of the Web》 性能優(yōu)化指南The Internet is ...
摘要:標(biāo)簽前端作者更多文章個(gè)人網(wǎng)站 Learning Notes - Understanding the Weird Parts of JavaScript 標(biāo)簽 : 前端 JavaScript [TOC] The learning notes of the MOOC JavaScript: Understanding the Weird Parts on Udemy,including...
摘要: Abstract Sockets are used nearly everywhere, but are one of the most severely misunderstood technologies around. This is a 10,000 foot overview of sockets. It’s not really a tutorial - you’ll s...
閱讀 870·2021-11-18 10:02
閱讀 1671·2019-08-30 15:56
閱讀 2570·2019-08-30 13:47
閱讀 2639·2019-08-29 12:43
閱讀 851·2019-08-29 11:19
閱讀 1783·2019-08-28 18:23
閱讀 2669·2019-08-26 12:23
閱讀 3007·2019-08-23 15:29