微信小程序如何阻止多層嵌套組件的點(diǎn)擊事件冒泡

先上結(jié)論

<view bindtap = 'outerTap'>
       <view  catchtap='innerTap' hover-stop-propagation='true'>刪除</view>
</view>

其中:

catchtap : 捕獲事件,組織冒泡
hover-stop-propagation :指定是否阻止本節(jié)點(diǎn)的祖先節(jié)點(diǎn)出現(xiàn)點(diǎn)擊態(tài)

原因呢廓俭,可以參考微信小程序的文檔事件

什么是事件

  • 事件是視圖層到邏輯層的通訊方式。
  • 事件可以將用戶的行為反饋到邏輯層進(jìn)行處理积锅。
  • 事件可以綁定在組件上切厘,當(dāng)達(dá)到觸發(fā)事件,就會(huì)執(zhí)行邏輯層中對(duì)應(yīng)的事件處理函數(shù)截粗。
  • 事件對(duì)象可以攜帶額外信息信姓,如 id, dataset, touches。

事件的使用方式

  • 在組件中綁定一個(gè)事件處理函數(shù)绸罗。
    如bindtap意推,當(dāng)用戶點(diǎn)擊該組件的時(shí)候會(huì)在該頁面對(duì)應(yīng)的Page中找到相應(yīng)的事件處理函數(shù)。
<view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me! </view>
  • 在相應(yīng)的Page定義中寫上相應(yīng)的事件處理函數(shù)从诲,參數(shù)是event左痢。
Page({
    tapName: function(event) {
    console.log(event)
    }
 })
  • 可以看到log出來的信息大致如下:
{
  "type":"tap",
  "timeStamp":895,
  "target": {
    "id": "tapTest",
    "dataset":  {
      "hi":"WeChat"
    }
  },
  "currentTarget":  {
    "id": "tapTest",
    "dataset": {
      "hi":"WeChat"
    }
  },
  "detail": {
    "x":53,
    "y":14
  },
  "touches":[{
    "identifier":0,
    "pageX":53,
    "pageY":14,
    "clientX":53,
    "clientY":14
  }],
  "changedTouches":[{
    "identifier":0,
    "pageX":53,
    "pageY":14,
    "clientX":53,
    "clientY":14
  }]
}

事件詳解

事件分類

事件分為冒泡事件和非冒泡事件:

  1. 冒泡事件:當(dāng)一個(gè)組件上的事件被觸發(fā)后,該事件會(huì)向父節(jié)點(diǎn)傳遞系洛。
  2. 非冒泡事件:當(dāng)一個(gè)組件上的事件被觸發(fā)后俊性,該事件不會(huì)向父節(jié)點(diǎn)傳遞。
    WXML的冒泡事件列表:


    事件列表.png

注:除上表之外的其他組件自定義事件如無特殊聲明都是非冒泡事件描扯,如<form/>submit事件定页,<input/>input事件,<scroll-view/>scroll事件绽诚,(詳見各個(gè)組件)

事件綁定和冒泡

事件綁定的寫法同組件的屬性典徊,以 key、value 的形式恩够。

  • key 以bindcatch開頭卒落,然后跟上事件的類型,如bindtap蜂桶、catchtouchstart儡毕。自基礎(chǔ)庫版本 1.5.0 起,在非原生組件中扑媚,bindcatch后可以緊跟一個(gè)冒號(hào)腰湾,其含義不變,如bind:tap疆股、catch:touchstart费坊。
  • value 是一個(gè)字符串,需要在對(duì)應(yīng)的 Page 中定義同名的函數(shù)旬痹。不然當(dāng)觸發(fā)事件的時(shí)候會(huì)報(bào)錯(cuò)附井。

bind事件綁定不會(huì)阻止冒泡事件向上冒泡,catch事件綁定可以阻止冒泡事件向上冒泡唱凯。

如在下邊這個(gè)例子中羡忘,點(diǎn)擊 inner view 會(huì)先后調(diào)用handleTap3handleTap2(因?yàn)閠ap事件會(huì)冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡磕昼,不再向父節(jié)點(diǎn)傳遞),點(diǎn)擊 middle view 會(huì)觸發(fā)handleTap2节猿,點(diǎn)擊 outer view 會(huì)觸發(fā)handleTap1票从。

<view id="outer" bindtap="handleTap1">
  outer view
  <view id="middle" catchtap="handleTap2">
    middle view
    <view id="inner" bindtap="handleTap3">
      inner view
    </view>
  </view>
</view>

事件的捕獲階段

自基礎(chǔ)庫版本 1.5.0 起漫雕,觸摸類事件支持捕獲階段。捕獲階段位于冒泡階段之前峰鄙,且在捕獲階段中浸间,事件到達(dá)節(jié)點(diǎn)的順序與冒泡階段恰好相反。需要在捕獲階段監(jiān)聽事件時(shí)吟榴,可以采用capture-bind魁蒜、capture-catch關(guān)鍵字,后者將中斷捕獲階段和取消冒泡階段吩翻。

在下面的代碼中兜看,點(diǎn)擊 inner view 會(huì)先后調(diào)用handleTap2handleTap4狭瞎、handleTap3细移、handleTap1

<view id="outer" bind:touchstart="handleTap1" capture-bind:touchstart="handleTap2">
  outer view
  <view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
    inner view
  </view>
</view>

如果將上面代碼中的第一個(gè)capture-bind改為capture-catch熊锭,將只觸發(fā)handleTap2弧轧。

<view id="outer" bind:touchstart="handleTap1" capture-catch:touchstart="handleTap2">
  outer view
  <view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
    inner view
  </view>
</view>

事件對(duì)象

如無特殊說明,當(dāng)組件觸發(fā)事件時(shí)碗殷,邏輯層綁定該事件的處理函數(shù)會(huì)收到一個(gè)事件對(duì)象精绎。
BaseEvent 基礎(chǔ)事件對(duì)象屬性列表:

屬性 類型 說明
type String 事件類型
timeStamp Integer 事件生成時(shí)的時(shí)間戳
target Object 觸發(fā)事件的組件的一些屬性值集合
currentTarget Object 當(dāng)前組件的一些屬性值集合

CustomEvent 自定義事件對(duì)象屬性列表(繼承 BaseEvent):

屬性 類型 說明
detail Object 額外的信息

TouchEvent 觸摸事件對(duì)象屬性列表(繼承 BaseEvent):

屬性 類型 說明
touches Array 觸摸事件,當(dāng)前停留在屏幕中的觸摸點(diǎn)信息的數(shù)組
changedTouches Array 觸摸事件锌妻,當(dāng)前變化的觸摸點(diǎn)信息的數(shù)組

特殊事件: <canvas> 中的觸摸事件不可冒泡代乃,所以沒有 currentTarget。

type
代表事件的類型从祝。

timeStamp
頁面打開到觸發(fā)事件所經(jīng)過的毫秒數(shù)襟己。

target

觸發(fā)事件的源組件。

屬性 類型 說明
id String 事件源組件的id
tagName String 當(dāng)前組件的類型
dataset Object 事件源組件上由data-開頭的自定義屬性組成的集合

currentTarget

事件綁定的當(dāng)前組件牍陌。

屬性 類型 說明
id String 當(dāng)前組件的id
tagName String 當(dāng)前組件的類型
dataset Object 當(dāng)前組件上由data-開頭的自定義屬性組成的集合

說明: target 和 currentTarget 可以參考上例中擎浴,點(diǎn)擊 inner view 時(shí),handleTap3 收到的事件對(duì)象 target 和 currentTarget 都是 inner毒涧,而handleTap2 收到的事件對(duì)象 target 就是 inner贮预,currentTarget 就是 middle。

dataset
在組件中可以定義數(shù)據(jù)契讲,這些數(shù)據(jù)將會(huì)通過事件傳遞給 SERVICE仿吞。 書寫方式: 以data-開頭,多個(gè)單詞由連字符-鏈接捡偏,不能有大寫(大寫會(huì)自動(dòng)轉(zhuǎn)成小寫)如data-element-type唤冈,最終在 event.currentTarget.dataset 中會(huì)將連字符轉(zhuǎn)成駝峰e(cuò)lementType。

示例:

<view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view>
Page({
  bindViewTap:function(event){
    event.currentTarget.dataset.alphaBeta === 1 // - 會(huì)轉(zhuǎn)為駝峰寫法
    event.currentTarget.dataset.alphabeta === 2 // 大寫會(huì)轉(zhuǎn)為小寫
  }
})

touches
touches 是一個(gè)數(shù)組银伟,每個(gè)元素為一個(gè) Touch 對(duì)象(canvas 觸摸事件中攜帶的 touches 是 CanvasTouch 數(shù)組)你虹。 表示當(dāng)前停留在屏幕上的觸摸點(diǎn)绘搞。

Touch 對(duì)象

屬性 類型 說明
identifier Number 觸摸點(diǎn)的標(biāo)識(shí)符
pageX, pageY Number 距離文檔左上角的距離,文檔的左上角為原點(diǎn) 傅物,橫向?yàn)閄軸夯辖,縱向?yàn)閅軸
clientX, clientY Number 距離頁面可顯示區(qū)域(屏幕除去導(dǎo)航條)左上角距離,橫向?yàn)閄軸董饰,縱向?yàn)閅軸

CanvasTouch 對(duì)象

屬性 類型 說明
identifier Number 觸摸點(diǎn)的標(biāo)識(shí)符
x, y Number 距離 Canvas 左上角的距離蒿褂,Canvas 的左上角為原點(diǎn) ,橫向?yàn)閄軸卒暂,縱向?yàn)閅軸

changedTouches

changedTouches 數(shù)據(jù)格式同 touches啄栓。 表示有變化的觸摸點(diǎn),如從無變有(touchstart)介却,位置變化(touchmove)谴供,從有變無(touchend、touchcancel)齿坷。

detail

自定義事件所攜帶的數(shù)據(jù)桂肌,如表單組件的提交事件會(huì)攜帶用戶的輸入,媒體的錯(cuò)誤事件會(huì)攜帶錯(cuò)誤信息永淌,詳見組件定義中各個(gè)事件的定義崎场。

點(diǎn)擊事件的detail 帶有的 x, y 同 pageX, pageY 代表距離文檔左上角的距離。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末遂蛀,一起剝皮案震驚了整個(gè)濱河市谭跨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌李滴,老刑警劉巖螃宙,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異所坯,居然都是意外死亡谆扎,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門芹助,熙熙樓的掌柜王于貴愁眉苦臉地迎上來堂湖,“玉大人,你說我怎么就攤上這事状土∥薹洌” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵蒙谓,是天一觀的道長(zhǎng)斥季。 經(jīng)常有香客問我,道長(zhǎng)累驮,這世上最難降的妖魔是什么泻肯? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任渊迁,我火速辦了婚禮慰照,結(jié)果婚禮上灶挟,老公的妹妹穿的比我還像新娘。我一直安慰自己毒租,他們只是感情好稚铣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著墅垮,像睡著了一般惕医。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上算色,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天抬伺,我揣著相機(jī)與錄音,去河邊找鬼灾梦。 笑死峡钓,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的若河。 我是一名探鬼主播能岩,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼萧福!你這毒婦竟也來了拉鹃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤鲫忍,失蹤者是張志新(化名)和其女友劉穎膏燕,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悟民,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡坝辫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了逾雄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片阀溶。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鸦泳,靈堂內(nèi)的尸體忽然破棺而出银锻,到底是詐尸還是另有隱情,我是刑警寧澤做鹰,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布击纬,位于F島的核電站,受9級(jí)特大地震影響钾麸,放射性物質(zhì)發(fā)生泄漏更振。R本人自食惡果不足惜炕桨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肯腕。 院中可真熱鬧献宫,春花似錦、人聲如沸实撒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽知态。三九已至捷兰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間负敏,已是汗流浹背贡茅。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留其做,地道東北人顶考。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像庶柿,于是被迫代替她去往敵國(guó)和親村怪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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