上週作了一個項目,發現一個DOM元素觸發touch事件,居然還會觸發別的元素的click事件。html
我先描述一下,當時遇到的問題。項目初始狀態是下面這張圖:android
我給右上方的的搜索按鈕,綁定了一個touchstart事件,點擊之後出現一個搜索框。至於爲何不直接綁定click事件,是由於touch事件響應更快,交互上更加流暢。iphone
這個搜索框右邊的搜索按鈕,綁定了一個click事件,點擊後當即觸發搜索。測試
當給這兩個DOM元素,都綁定好事件之後。咱們分別用android和iphone手機進行測試,獲得了一個共同的結果。htm
當手指接觸到搜索圖標,當即觸發了該元素的touchstart事件,下面的搜索框也隨之顯示。尚未完,這時候手指還會觸發搜索按鈕的click事件,致使搜索框提交。blog
整個交互變成了,點擊搜索圖標,就觸發了搜索。這確定不是咱們想要的。事件
而後就查一些資料,獲得了一些理論知識。最重要的一個就是事件流的概念,點擊事件能夠分解成多個事件。ip
在移動端,手指點擊一個元素,會通過:touchstart --> touchmove -> touchend --》click。io
事件流自己會持續進行下去的。event
作了幾個demo驗證了一下,上面的理論。
首先給一個元素同時綁定touchstart和click事件,看誰先觸發。
html:
<style> .content{ height:500px; background:#F00; } </style> <div class="content"></div>
var content = document.querySelector(".content"); content.addEventListener("touchend", function(){ content.style.background = "#0F0"; });content.addEventListener("click", function(){ content.style.background = "#00F"; });
上面邏輯是給content類名的div,綁定一個touch事件和一個click事件。分別讓div的背景色變成綠色和藍色。
手機測試一下,點擊一下,div是先變成綠色而後又變成藍色。
那能不能只觸發touch事件,不去觸發click事件呢?查閱相關資料, 發現了preventDefault()的方法,阻止事件的默認行爲。
var content = document.querySelector(".content"); content.addEventListener("touchstart", function(e){ e.preventDefault(); content.style.background = "#0F0"; }) content.addEventListener("click", function(e){ content.style.background = "#00F"; });
經過 preventDefault()方法,能夠阻止後面事件的觸發。