先上結(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
}]
}
事件詳解
事件分類
事件分為冒泡事件和非冒泡事件:
- 冒泡事件:當(dāng)一個(gè)組件上的事件被觸發(fā)后,該事件會(huì)向父節(jié)點(diǎn)傳遞系洛。
-
非冒泡事件:當(dāng)一個(gè)組件上的事件被觸發(fā)后俊性,該事件不會(huì)向父節(jié)點(diǎn)傳遞。
WXML的冒泡事件列表:
注:除上表之外的其他組件自定義事件如無特殊聲明都是非冒泡事件描扯,如<form/>
的submit
事件定页,<input/>
的input
事件,<scroll-view/>
的scroll
事件绽诚,(詳見各個(gè)組件)
事件綁定和冒泡
事件綁定的寫法同組件的屬性典徊,以 key、value 的形式恩够。
- key 以
bind
或catch
開頭卒落,然后跟上事件的類型,如bindtap
蜂桶、catchtouchstart
儡毕。自基礎(chǔ)庫版本 1.5.0 起,在非原生組件中扑媚,bind
和catch
后可以緊跟一個(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)用handleTap3
和handleTap2
(因?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)用handleTap2
、handleTap4
狭瞎、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 代表距離文檔左上角的距離。