點透 解決方案

2022-04-03 10:29:24 字數 3397 閱讀 3791

點透 & 解決方案

學習map:

再現點透現象請使用一下方式:

手機訪問傳送門

或者開啟chrome手機檢視並開啟touch screen

zepto-隱藏元素-點透

**:zepto-最新-沒有點透

**:原生js-隱藏元素-點透

**:原生js-元素出現-點透

**:綜上,導致點透現象出現的場景:

元素z軸重疊;

繫結了touch事件的元素消失或移走;

繫結有類click事件的元素出現在點選區域;

ps:a鏈結的href跳轉、input、select等表單元素的聚焦並彈起軟鍵盤,等觸發的事件和click一樣,由於歷史原因在手機端也會表現出300ms延遲,因此也都可以看做是click事件,我叫他類click事件,demo可用爪機狠戳事件觸發順序&click延遲demo或者複製鏈結到連圖生成***後掃一掃。類click事件,也是一種瀏覽器預設行為,可被event.preventdefault()阻止。

**:從事件觸發順序&click延遲demo這個demo可以看出:

由於我們在touchend階段z軸層級已經發生了變化,當click被觸發時候,能夠被點選的元素則是當前z軸離使用者最近的層,根據click事件的觸發規則:

在被觸發時,當前有繫結click事件的元素顯示,且在面朝使用者的最前端時,才觸發click事件
因此touchend之後符合條件的繫結了click事件的元素被點透。

總而言之:出現點透是由於移動端click事件遲於touch事件被觸發導致的。

不優雅的辦法:

1. 對於預設繫結了類click事件的元素(如a、input、select等)

2. 對於沒有預設繫結類click事件的元素

統一使用touch事件。z軸上都繫結touchstarttouchendtap不用阻止預設行為也不會穿透。

使用上述方法有很明顯的缺點和不方便:

使用touchend + preventdefault要在同乙個元素上繫結2個事件,zepto可以封裝成tap事件,我們也可以,自定義tap事件阻止點透

**:在本demo中,雖然沒有出現點透現象,但是點選出現彈層以後你會發現點選a鏈結、span、input都沒有任何反映了,這是因為在touchend裡阻止瀏覽器預設行為,觸發自定義tap事件,不僅會阻止掉了input的軟鍵盤彈出,還會阻止一切非tap事件,解決辦法就是使用合成的click事件去覆蓋會延遲的click事件。

重寫click事件

**:

event.initevent('click', bubbles, true);

touch_target.addeventlistener("click", handle, false);

這樣再次點選,彈層上的a鏈結和span的click事件都響應地很迅速,然而input和select的彈出軟鍵盤的功能被閹割了,實際上input彈出軟鍵盤的事件是focus()事件

3. fastclick

讀fastclick原始碼

layer.removeeventlistener('touchend', this.ontouchend, false);

fastclick.prototype.ontouchend = function(event)

targetelement = forelement;

}} else if (this.needsfocus(targetelement))

this.focus(targetelement);

this.sendclick(targetelement, event);

if (!deviceisios || targettagname !== 'select')

return false;

}// needsfocus

fastclick.prototype.needsfocus = function(target)

// no point in attempting to focus disabled inputs

return !target.disabled && !target.readonly;

default:

return (/\bneedsfocus\b/).test(target.classname);

}};// sendclick

fastclick.prototype.sendclick = function(targetelement, event)

touch = event.changedtouches[0];

// synthesise a click event, with an extra attribute so it can be tracked

clickevent = document.createevent('mouseevents');

clickevent.initmouseevent(this.determineeventtype(targetelement), true, true, window, 1, touch.screenx, touch.screeny, touch.clientx, touch.clienty, false, false, false, false, 0, null);

clickevent.forwardedtouchevent = true;

targetelement.dispatchevent(clickevent);

};

上面**的意思就是:在目標元素上繫結touchend事件,在事件處理函式裡,如果是需要focus的表單元素被點選,則先觸發他們的focus事件,再觸發自定義的click事件,fastclick之所以大,就是因為對很多表單元素在各個系統的各個版本的不同表現做了相容,不僅解決了click以及類click的延遲問題,而且當檢測到當前頁面使用了基於標籤或者touch-action屬性的解決方案時,會靜默退出。可以說,這是真正的跨平台方案出來之前一種很好的變通方案。而zepto只是為普通的點選事件封裝了乙個更快的tap事件,類click事件的延遲問題並沒有得到解決,而且移動端使用的tap事件,如果沒做裝置判斷相容pc的話,pc端的點選事件將得不到響應,這會很影響**的可用性和可訪問性。不過zepto封裝了一系列移動端很需要的功能,比如swipeleft、swiperight、swipeup、等等,二者各有春秋,兼併兩者優勢的庫我目前沒遇到,不過可以嘗試自己寫乙個,加個todo吧。

4. tap.js

tap.js原始碼只有不到200行,大致看了下,並不能解決類click的延遲問題,雞肋!

mysql 解決方案 Mysql解決方案

mysql解決方案 一 centos7安裝mysql5.7 wget rpm uvh mysql80 community release el7 3.noarch.rpm yum repolist all grep mysql 發現預設mysql8.0是預設安裝的,然而我們要安裝的是mysql5.7...

快取雪崩 快取穿透 快取擊透常見解決方案

快取雪崩是指快取在同一時間大面積失效,所以,後面的請求都會落到資料庫上,造成資料庫短時間內承受大量請求而崩掉。快取穿透是指快取和資料庫中都沒有的資料,導致所有請求都落在了資料庫上,造成段時間內承受大量的請求而奔掉。快取擊穿是指快取中沒有但資料庫中有的資料 一般是指快取時間到期 這時由於併發使用者特別...

mobile 點透 傳透

點透 傳透 pc 的 click 事件 在移動端,會有 300 ms 的延遲。就是因為避免和手機雙擊行為發生衝突 當點選 非文字覆蓋區域 時,盒子正常消失。當點選 文字區域時,頁面發生跳轉。無論點選哪個區域,只要是點選盒子,盒子都消失,而不影響 a click 事件監聽,缺點 pc 端的 click...