歡迎關注富途web開發團隊 ,缺人從衆css
有一次給公司作了個自適應的的費用介紹頁,主要是關於收費標準的調整,老闆表示很重視,適用人羣也不少,因此也反饋獲得幾個不常遇到的問題,其中一個就是關於touchstart
與click
事件的問題。這裏記錄一下,歡迎指正。前端
某天中午,開發了好幾天的費用介紹頁終於上線了。運營同窗滿懷信心地發送了收費標準頁面的推廣消息,而後咱們都瀟灑地吃午餐去了。正吃着午餐的時候,收到微信羣中某客戶的反饋:咱們的頁面最關鍵的地方——收費詳情點擊沒有反應!android
隨後咱們查看了前端錯誤上報和日誌,沒有任何線索。與客戶確認環境,客戶使用的是 windows PC 。web
但奇怪的是,我測試了多臺設備,仍然沒法重現問題。在同事的機器上也沒能復現這個問題。windows
咱們從新審視了一遍事件綁定的代碼,發現其實很是簡單。bash
var tap = 'ontouchstart' in window ? 'touchstart' : 'click';
wrap.addEvenListener(tap, function(){
signUp();
});
複製代碼
惟一有點特殊的就是咱們的頁面是自適應的,爲了不移動端點擊 300ms 延遲,在綁定前作了一下判斷,移動端綁定了touchstart
事件,PC 端綁定了click
事件。然而這段代碼看起來也是人畜無害,並不至於致使點擊沒有反應。微信
咱們再次詢問了客戶更詳細的環境信息,得到了一個很是關鍵的信息,客戶使用的是聯想的筆記本。因爲在 surface 出來的時候組裏有同事關注過,想起來當時聯想也出了不少觸屏筆記本。因而和客戶再次聯繫,確認了他使用的就是聯想的觸屏筆記本。iphone
至此問題就很是明確了,問題最終仍是定位在綁定的「點擊」事件上。咱們在檢測時只是粗暴地檢測了設備是否支持觸控事件,卻忽略了支持觸控事件的仍然多是 PC 設備,客戶仍然可能經過點擊鼠標來進行操做。這實際上反映出咱們忽略了用戶設備的多樣性,開發的時候對用戶設備作了太多的假設,最終致使咱們覺得它是一臺手機,結果它是一臺貨真價實的筆記本電腦。函數
概括起來,關鍵的點就是:測試
touchstart
和click
事件;touchstart
事件,默認必然會致使觸發click
事件,可是觸發click
事件,不必定會致使touchstart
事件被觸發;touchstart
事件,可是鼠標操做只能觸發click
,致使touchstart
不觸發;至此,問題的緣由已經分析完畢,如何應對又成了一個問題。這個問題的關鍵在於肯定不一樣設備上使用「點擊」事件的策略。大體分爲以下幾種:
function isMobile() {
return navigator.userAgent.match(/(blackberry|configuration\/cldc|hp |hp-|htc |htc_|htc-|iemobile|kindle|midp|mmp|motorola|mobile|nokia|opera mini|opera |Googlebot-Mobile|YahooSeeker\/M1A1-R2D2|android|iphone|ipod|mobi|palm|palmos|pocket|portalmmm|ppc;|smartphone|sonyericsson|sqh|spv|symbian|treo|up.browser|up.link|vodafone|windows ce|xda |xda_)/i) ? true : false;
}
var tap = isMobile() ? 'touchstart' : 'click';
複製代碼
//引入FastClick
var FastClick = require('tool-fastclick');
//頁面初始化時調用
new FastClick(document.body);
複製代碼
注:
tool-fastclick
是組內 fork 的 FastClick 版本,目前沒有開源。咱們對其中存在的問題進行了一部分修復,好比:同個頁面有多個 select 框選擇時,會跳選項的 bug 。
其實最好的方案是不要在綁定的時候進行判斷,而是對touchstart
和click
同時綁定,可是在touchstart
觸發的時候暫時取消後續 click 的響應。
具體的實施方式有三種:
touchstart
事件響應中調用preventDefault()
方法,阻止後續click
事件的觸發touchstart
事件中設置一些標記,或者取消click
事件的綁定,使得click
事件觸發時不會觸發咱們綁定的邏輯,在一段時間(例如300-500ms)後再恢復固然,和上面同樣,每種方案都有利弊。
方案1取消了後續click
事件的觸發,在多個事件綁定疊加或者多人合做的時候,有可能致使一些依賴click
事件的邏輯出現bug。
方案2和方案3的原理基本同樣,實施起來有必定的複雜度,並且本質上屬於 hack 的方案,應對一些很是規場景時就不適用了。好比須要快速連續點擊的場景,或者用戶點擊很是慢的場景等等。
總之,沒有萬全之策,呵呵……
有人可能會對文章最前提到的收費介紹頁比較感興趣,來了,看這裏。