移動端的touch click事件的理解+點透

移動端在touch上一共有4個事件

touchstart touchmove touchend touchcancel, touchcancel, 一般來說,它們執(zhí)行的順序為 touchstart -> touchmove -> touchend -> touchcancel . 其中touchcancel一般情況下不會觸發(fā)剔应,也不是這里討論的焦點。

這里會結(jié)合click對上面的事件進行討論, touch發(fā)生在click之前

先上段代碼,直觀感受一下

<!DOCTYPE html>
<html>
  <head>
    <style type="text/css">
      #level0 {
        /* width: 500px;
        height: 500px; */
      }

      #level1-0 {
        background: red;
        width: 500px;
        height: 500px;
      }

      #level1-1 {
        background: green;
        width: 500px;
        height: 500px;
      }
    </style>
  </head>
  <body>
    <div id="level0">
      <div id="level1-0">
      </div>
      <div id="level1-1">
      </div> 
    </div>
  </body>
  <script type="text/javascript">

    var level10 = document.getElementById("level1-0");

    level10.addEventListener('touchstart', function(e) {
      console.log(1);
    });

    level10.addEventListener('touchmove', function(e) {
      console.log(2);
    });

    level10.addEventListener('touchend', function(e) {
      console.log(3);
    });

    level10.onclick = function() {
      console.log(5);
    }

    document.body.onclick = function() {
      console.log('6');
    }

  </script>
</html>

在紅色區(qū)域點擊會出現(xiàn)什么效果呢造虏? 出現(xiàn)的是 1 3 5 6, 奇怪了 touchmove 為何不執(zhí)行麦箍,因為我們并沒有移動漓藕,也就是說,必須觸碰到屏幕上面挟裂,而且發(fā)生了移動動作享钞,touchmove才執(zhí)行,現(xiàn)在我們觸碰到,而且手指稍微動一下栗竖,發(fā)現(xiàn)輸出的效果是暑脆, 1 2(+) 3, 其中touchmove 可能觸發(fā)多次,又奇怪了狐肢, click為何不執(zhí)行添吗, 因為 click執(zhí)行的條件是 點擊, 而且不移動 所以一般情況下份名,我們可以理解成 touchmove和click是相斥的碟联。

我們知道,當一個用戶在點擊屏幕的時候僵腺,系統(tǒng)會觸發(fā)touch事件和click事件鲤孵,touch事件優(yōu)先處理,touch事件經(jīng)過 捕獲辰如,處理, 冒泡 一系列流程處理完成后普监, 才回去觸發(fā)click事件

既然touch事件和click事件有了優(yōu)先級別,那么能不能在touch階段取消掉系統(tǒng)觸發(fā)的click事件呢琉兜?當然是可以的鹰椒,瀏覽器提供了這樣的能力。在touch事件里面呕童,調(diào)用e.preventDefault() 就可以阻止本次點擊系統(tǒng)觸發(fā)的click事件漆际,即本次相關(guān)的click都不會執(zhí)行

把上面代碼稍微加一點

    level10.addEventListener('touchstart', function(e) {
      console.log(1);
      e.preventDefault();
    });

點擊的時候 發(fā)現(xiàn) 只有 1 3, 說明click被阻止了夺饲,當然在touchend里面加效果也一樣奸汇,所以 在touch事件里面加 e.preventDefault可以取消系統(tǒng)產(chǎn)生的click事件, 當然不會阻止后面的touch事件往声。

用個具體的例子看看 如何解決點透問題

產(chǎn)生點透問題的原因擂找, 可以先看看代碼吧

<!DOCTYPE html>
<html>
  <head>
    <style type="text/css">
      #level0 {
        /* width: 500px;
        height: 500px; */
        position: relative;
      }

      #level1-0 {
        position: absolute;
        z-index: 1;
        background: red;
        width: 500px;
        height: 500px;
      }

      #level1-1 {
        background: green;
        width: 500px;
        height: 500px;
      }
    </style>
  </head>
  <body>
    <div id="level0">
      <div id="level1-0">
      </div>
      <div id="level1-1">
      </div> 
    </div>
  </body>
  <script type="text/javascript">

    var level10 = document.getElementById("level1-0");
    var level11 = document.getElementById("level1-1");


    level10.addEventListener('touchstart', function(e) {
      level10.style.display = 'none';
    });

    level11.onclick = function() {
      console.log('level11莫名被點擊了');
    }

  </script>
</html>

本來是 level1-0 和 level1-1是兄弟節(jié)點,即他們之間不會發(fā)生什么 事件傳遞浩销, 目前l(fā)evel1-0相當于一個覆蓋層贯涎,覆蓋在level1-1上面, 按理說點擊 level1-0的時候慢洋,level1-0會阻擋所有的事件塘雳,事件不會傳遞給level1-1,當點擊level1-0的時候普筹,實際上level1-1也發(fā)生了點擊事件败明,即上面的輸出結(jié)果為
level1-0消失, 輸出 level11莫名被點擊了, 這就是點透

點透發(fā)生的條件太防,

  1. A 和 B不是后代繼承關(guān)系(如果是后代繼承關(guān)系的話妻顶,就直接是冒泡子類的話題了)
  2. A發(fā)生touch, A touch后立即消失, B事件綁定click
  3. A z-index大于B讳嘱,即A顯示在B浮層之上

點透發(fā)生的理由: 當手指觸摸到屏幕的時候幔嗦,系統(tǒng)生成兩個事件,一個是touch 一個是click沥潭,touch先執(zhí)行崭添,touch執(zhí)行完成后,A從文檔樹上面消失了叛氨,而且由于移動端click還有延遲200-300ms的關(guān)系呼渣,當系統(tǒng)要觸發(fā)click的時候,發(fā)現(xiàn)在用戶點擊的位置上面寞埠,目前離用戶最近的元素是B屁置,所以就直接把click事件作用在B元素上面了.

那如何才能解決點透問題呢? 還記得我之前說過么仁连,系統(tǒng)提供了先觸發(fā)的touch事件去取消系統(tǒng)生成的click事件蓝角,所以只要在touch事件的某個處理函數(shù)中 執(zhí)行 e.preverDefault即可, 一般我們在touchend中執(zhí)行

在上面代碼中饭冬,加上這句就完美解決了

    level10.addEventListener('touchend', function(e) {
      e.preventDefault();
    });

當然點透問題使鹅,還有其他的解決方法,關(guān)鍵是 要么是需求本次系統(tǒng)生成的click事件昌抠,要么是當系統(tǒng)觸發(fā)click的時候患朱,當前的觸發(fā)touch的那個dom節(jié)點還存在。比如將其一延遲3s在關(guān)閉

      setTimeout(() => {
        level10.style.display = 'none';
      }, 300);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末炊苫,一起剝皮案震驚了整個濱河市裁厅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌侨艾,老刑警劉巖执虹,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異唠梨,居然都是意外死亡袋励,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門当叭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來茬故,“玉大人,你說我怎么就攤上這事科展【危” “怎么了糠雨?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵才睹,是天一觀的道長。 經(jīng)常有香客問我,道長琅攘,這世上最難降的妖魔是什么垮庐? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮坞琴,結(jié)果婚禮上哨查,老公的妹妹穿的比我還像新娘。我一直安慰自己剧辐,他們只是感情好寒亥,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著荧关,像睡著了一般溉奕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上忍啤,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天加勤,我揣著相機與錄音,去河邊找鬼同波。 笑死鳄梅,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的未檩。 我是一名探鬼主播戴尸,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼冤狡!你這毒婦竟也來了校赤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤筒溃,失蹤者是張志新(化名)和其女友劉穎马篮,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體怜奖,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡浑测,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了歪玲。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片迁央。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖滥崩,靈堂內(nèi)的尸體忽然破棺而出岖圈,到底是詐尸還是另有隱情,我是刑警寧澤钙皮,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布蜂科,位于F島的核電站顽决,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏导匣。R本人自食惡果不足惜才菠,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望贡定。 院中可真熱鬧赋访,春花似錦、人聲如沸缓待。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旋炒。三九已至田晚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間国葬,已是汗流浹背贤徒。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留汇四,地道東北人接奈。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像通孽,于是被迫代替她去往敵國和親序宦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

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