移動(dòng)端頁(yè)面點(diǎn)擊穿透問題

一佳鳖、click與300ms延遲

? ? 移動(dòng)端瀏覽器提供了一個(gè)特殊的功能:雙擊放大

300ms的延遲就是來(lái)自于這里吩案,用戶碰觸頁(yè)面之后棚赔,需要等待一段時(shí)間來(lái)判斷是不是雙擊(double tap)動(dòng)作,而不是立即響應(yīng)單擊(click),等待的這段時(shí)間大約是300ms徘郭。

之前有過簡(jiǎn)單介紹(黯羽輕揚(yáng):HTML5觸摸事件

移動(dòng)事件提供了touchstart靠益、touchmove、touchend卻沒有提供tap支持残揉,主流框架(庫(kù))都是手動(dòng)實(shí)現(xiàn)了自定義tap事件胧后,以消除300ms延遲,提高頁(yè)面響應(yīng)速度抱环,對(duì)于簡(jiǎn)單的頁(yè)面壳快,可以把touchstart或者touchend當(dāng)做tap來(lái)用,但是存在一些問題镇草,比如手直接觸目標(biāo)元素眶痰,按住不放,慢慢移除響應(yīng)區(qū)域梯啤,會(huì)觸發(fā)touchstart事件執(zhí)行對(duì)應(yīng)的事件處理器(本不應(yīng)該觸發(fā))竖伯,touchend事件也存在類似的問題。

此外因宇,使用原生touch事件也存在點(diǎn)擊穿透的問題七婴,因?yàn)閏lick是在touch系列事件發(fā)生大約300ms才觸發(fā)的,混用touch和click肯定會(huì)導(dǎo)致點(diǎn)透問題察滑,下面詳細(xì)介紹

二本姥、點(diǎn)擊穿透問題

點(diǎn)擊穿透現(xiàn)象有三種

? ? *點(diǎn)擊穿透問題:點(diǎn)擊蒙層(mask)上的關(guān)閉按鈕,蒙層消失后發(fā)現(xiàn)觸發(fā)了按鈕下面元素的click事件
蒙層關(guān)閉按鈕綁定的是touch事件杭棵,而按鈕下邊元素綁定的是click事件,touch事件觸發(fā)之后,蒙層消失了魂爪,300ms后這個(gè)點(diǎn)的click事件fire先舷,event的target自然就是按鈕下面的元素,因?yàn)榘粹o跟蒙層一起消息了滓侍。

? ? *跨頁(yè)面點(diǎn)擊穿透事件:如果按鈕下面恰好是一個(gè)href屬性的a標(biāo)簽蒋川,那么頁(yè)面就會(huì)法神跳轉(zhuǎn),因?yàn)閍標(biāo)簽跳轉(zhuǎn)默認(rèn)是click事件觸發(fā)撩笆,所以原理和上面的完全相同

? ? *另一種跨頁(yè)面點(diǎn)擊穿透問題:這次沒有mask了捺球,直接點(diǎn)擊頁(yè)內(nèi)按鈕跳轉(zhuǎn)至新頁(yè),然后發(fā)現(xiàn)新頁(yè)面中對(duì)應(yīng)位置元素的click事件被觸發(fā)

和蒙層的道理一樣夕冲,js控制頁(yè)面跳轉(zhuǎn)的邏輯如果是綁定在touch事件上的氮兵,而且新頁(yè)面中對(duì)應(yīng)位置的元素綁定的是click事件,而且頁(yè)面在300ms內(nèi)完成了跳轉(zhuǎn)歹鱼,三個(gè)條件同時(shí)滿足泣栈,就出現(xiàn)這種情況了

非要細(xì)分的話還有第四種,不過概率很低弥姻,就是新頁(yè)面中對(duì)應(yīng)位置元素恰好是a標(biāo)簽南片,然后就發(fā)生連續(xù)跳轉(zhuǎn)了。庭敦。疼进。諸如此類的,都是點(diǎn)擊穿透問題

三秧廉、為什么會(huì)出現(xiàn)點(diǎn)透

click延遲伞广、延遲、還是延遲

在移動(dòng)端不使用click而用touch事件代替觸摸是因?yàn)閏lick事件有著明顯的延遲定血,具體touchstart與click的區(qū)別如下:

? ? *touchstart:在這個(gè)DOM(或者冒泡到這個(gè)DOM)上手指觸摸開始即能立即出發(fā)

? ? *click:在這個(gè)DOM(或者冒泡這個(gè)DOM)上手指觸摸開始赔癌,且手指未在屏幕上移動(dòng)(某些<a href=”http://www.it165.net/edu/ewl/” target=”_blank” class=”keylink”>瀏覽器</a>允許移動(dòng)一個(gè)非常小的位移值),且在這個(gè)DOM元素上手指離開屏幕澜沟,且觸摸和離開屏幕之間的間隔時(shí)間較短(某些瀏覽器不檢測(cè)間隔時(shí)間灾票,也會(huì)觸發(fā)click)才能觸發(fā)

也就是說,事件的觸發(fā)事件按照由早到晚排列為:touchstart早于touchend早于click茫虽。亦即click的觸發(fā)是有延遲的刊苍,這個(gè)時(shí)間大概在300ms左右(即使給元素綁定的是touch事件,touchstart=>touchend=>click濒析,click事件依然會(huì)被觸發(fā))

由于我們?cè)趖ouchstart階段就已經(jīng)隱藏了罩層A夹纫,當(dāng)click被觸發(fā)的時(shí)候递惋,能夠被點(diǎn)擊的元素則是罩層下面的B元素綁定的事件,根據(jù)click事件的觸發(fā)規(guī)則:

只有在被觸發(fā)的時(shí)候,當(dāng)前有click事件的元素顯示素标,且在面朝用戶的最前端時(shí)七扰,才出發(fā)click事件。

由于B綁定了click事件(或者B本身默認(rèn)存在click事件),所以B的click事件被觸發(fā)荣暮,產(chǎn)生了點(diǎn)透的情況。

解決方案

對(duì)于B元素本身沒有默認(rèn)click事件的情況(無(wú)a標(biāo)簽等)罩驻,應(yīng)統(tǒng)一使用touch事件穗酥,統(tǒng)一代碼風(fēng)格,并且由于click事件在移動(dòng)端的延遲要大很多惠遏,不利于用戶體驗(yàn)砾跃,所以關(guān)于觸摸事件應(yīng)盡量使用touch相關(guān)事件。

對(duì)于B元素本身存在默認(rèn)click事件的情況,應(yīng)及時(shí)取消A元素的默認(rèn)點(diǎn)擊事件节吮,從而阻止click事件的產(chǎn)生抽高。即應(yīng)在上例的handle函數(shù)中添加代碼如下:

對(duì)于遮蓋浮層,由于遮蓋浮層的點(diǎn)擊即使有小延遲也是沒有關(guān)系的课锌,反而會(huì)有疑似更好的用戶體驗(yàn)厨内,所以這種情況,可以針對(duì)遮蓋浮層自己采用click事件渺贤,這樣就不會(huì)出現(xiàn)點(diǎn)透問題雏胃。

四、解決方案

問題已經(jīng)很明了了志鞍,有很多解決方案瞭亮,但是思路不外乎2種:
1、不要混用touch和click

? ? ? ? 既然touch之后300ms會(huì)觸發(fā)click固棚,只用touch或者只用click自然不會(huì)存在問題

2统翩、吃掉或者消費(fèi)掉touch之后的click

? ? ? ? 依舊用tap,只是在可能發(fā)生點(diǎn)擊穿透的情形做額外的處理此洲,拿個(gè)東西來(lái)?yè)踝』蛘遲ap后延遲350ms在隱藏mask厂汗、pointer-events、在下面元素的事件處理器里做檢測(cè)(配合全局flag)等等呜师,能吃掉就行

詳細(xì)解決方案

1娶桦、只用touch

? ? 最簡(jiǎn)單的解決方案,完美解決點(diǎn)擊穿透事件

把頁(yè)面內(nèi)所有click全部換成touch事件(touchstart汁汗、touchend衷畦、tap),需要特別注意a標(biāo)簽,a標(biāo)簽的href也是click知牌,需要去掉換成js控制的跳轉(zhuǎn)祈争,或者直接改成span+tap控制跳轉(zhuǎn)。如果要求不高角寸,不在乎滑走或者滑進(jìn)來(lái)觸發(fā)事件的話菩混,span+touchend就可以了忿墅。畢竟tap需要引入第三方庫(kù)

不用a標(biāo)簽其實(shí)沒什么,移動(dòng)app開發(fā)不用考慮SEO沮峡,即便用了a標(biāo)簽球匕,一般也會(huì)去掉所有默認(rèn)樣式,不如直接用span

2帖烘、只是用click

下下策,因?yàn)閹?lái)300ms延遲橄杨,頁(yè)面內(nèi)任何一個(gè)滴定儀監(jiān)護(hù)都將增加300ms延遲秘症,想想都慢

不用touch就不會(huì)存在touch之后300ms觸發(fā)click的問題,如果交互性要求不高可以這么做式矫,?強(qiáng)烈不推薦?乡摹,快一點(diǎn)總是好的

3、拿個(gè)東西來(lái)?yè)踝?/p>

比較笨的方法采转,不推薦用

4聪廉、tap后延遲350ms在隱藏mask

改動(dòng)最小,缺點(diǎn)是隱藏mask變慢了故慈,350ms還是能感覺到慢的

只需要針對(duì)mask做處理就行板熊,改動(dòng)非常小,如果要求不高的話察绷,用這個(gè)比較省力

5干签、pointer-events

比較麻煩且有缺陷,不建議使用

mask隱藏后拆撼,給按鈕下面元素添加上pointer-events:none;樣式容劳,讓click穿過去,350ms后去掉這個(gè)樣式闸度,恢復(fù)響應(yīng)

缺陷是mask消失后的的350ms內(nèi)竭贩,用戶可以看到按鈕下面的元素點(diǎn)著沒反應(yīng),如果用戶手速很快的話一定會(huì)發(fā)現(xiàn)

在下面元素的事件處理器里做檢測(cè)(配合全局flag)

6莺禁、比較麻煩留量,?不建議使用

全局flag記錄按鈕點(diǎn)擊的位置(坐標(biāo)點(diǎn)),在下面元素的事件處理器里判斷event的坐標(biāo)點(diǎn)睁宰,如果相同則是那個(gè)可惡的click肪获,拒絕響應(yīng)

上面說的只是想法,沒測(cè)試過柒傻,實(shí)在不行就用記錄時(shí)間戳判斷孝赫,等待350ms,這樣就和?pointer-events?差不多

7红符、fastclick

好用的解決方案青柄,不介意多加載幾kb的話伐债,不建議使用,因?yàn)橛腥擞龅搅薭ug致开,更多信息請(qǐng)查看:Fastclick 導(dǎo)致click事件觸發(fā)兩次的問題

首先引入fastclick庫(kù)峰锁,再把頁(yè)面內(nèi)所有touch事件都換成click,其實(shí)稍微有點(diǎn)麻煩双戳,建議引入這幾KB就為了解決點(diǎn)透問題不值得虹蒋,不如用第一種方法呢

參考文檔:http://www.uedsc.com/through-the-click-point-in-the-development-of-web.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市飒货,隨后出現(xiàn)的幾起案子魄衅,更是在濱河造成了極大的恐慌,老刑警劉巖塘辅,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晃虫,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡扣墩,警方通過查閱死者的電腦和手機(jī)哲银,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)呻惕,“玉大人荆责,你說我怎么就攤上這事◇∪冢” “怎么了草巡?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)型酥。 經(jīng)常有香客問我山憨,道長(zhǎng),這世上最難降的妖魔是什么弥喉? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任郁竟,我火速辦了婚禮,結(jié)果婚禮上由境,老公的妹妹穿的比我還像新娘棚亩。我一直安慰自己,他們只是感情好虏杰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布讥蟆。 她就那樣靜靜地躺著,像睡著了一般纺阔。 火紅的嫁衣襯著肌膚如雪瘸彤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天笛钝,我揣著相機(jī)與錄音质况,去河邊找鬼愕宋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛结榄,可吹牛的內(nèi)容都是我干的中贝。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼臼朗,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼邻寿!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起视哑,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤老厌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后黎炉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡醋拧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年慷嗜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丹壕。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡庆械,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出菌赖,到底是詐尸還是另有隱情缭乘,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布琉用,位于F島的核電站堕绩,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏邑时。R本人自食惡果不足惜奴紧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望晶丘。 院中可真熱鬧黍氮,春花似錦、人聲如沸浅浮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)滚秩。三九已至专执,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間叔遂,已是汗流浹背他炊。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工争剿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人痊末。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓蚕苇,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親凿叠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子涩笤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容