微信小程式如何阻止多層巢狀元件的點選事件冒泡
先上結論
<view bindtap = 'outerTap'>
<view catchtap='innerTap' hover-stop-propagation='true'>刪除</view>
</view>
其中:
catchtap : 捕獲事件,組織冒泡
hover-stop-propagation :指定是否阻止本節點的祖先節點出現點選態
原因呢,可以參考微信小程式的文件事件
什麼是事件
- 事件是檢視層到邏輯層的通訊方式。
- 事件可以將使用者的行為反饋到邏輯層進行處理。
- 事件可以繫結在元件上,當達到觸發事件,就會執行邏輯層中對應的事件處理函式。
- 事件物件可以攜帶額外資訊,如 id, dataset, touches。
事件的使用方式
- 在元件中繫結一個事件處理函式。
如bindtap,當使用者點選該元件的時候會在該頁面對應的Page中找到相應的事件處理函式。
<view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me! </view>
- 在相應的Page定義中寫上相應的事件處理函式,引數是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
}]
}
事件詳解
事件分類
事件分為冒泡事件和非冒泡事件:
- 冒泡事件:當一個元件上的事件被觸發後,該事件會向父節點傳遞。
-
非冒泡事件:當一個元件上的事件被觸發後,該事件不會向父節點傳遞。
WXML的冒泡事件列表:
注:除上表之外的其他元件自定義事件如無特殊宣告都是非冒泡事件,如<form/>
的submit
事件,<input/>
的input
事件,<scroll-view/>
的scroll
事件,(詳見各個元件)
事件繫結和冒泡
事件繫結的寫法同元件的屬性,以 key、value 的形式。
- key 以
bind
或catch
開頭,然後跟上事件的型別,如bindtap
、catchtouchstart
。自基礎庫版本 1.5.0 起,在非原生元件中,bind
和catch
後可以緊跟一個冒號,其含義不變,如bind:tap
、catch:touchstart
。 - value 是一個字串,需要在對應的 Page 中定義同名的函式。不然當觸發事件的時候會報錯。
bind
事件繫結不會阻止冒泡事件向上冒泡,catch
事件繫結可以阻止冒泡事件向上冒泡。
如在下邊這個例子中,點選 inner view 會先後呼叫handleTap3
和handleTap2
(因為tap事件會冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡,不再向父節點傳遞),點選 middle view 會觸發handleTap2
,點選 outer view 會觸發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>
事件的捕獲階段
自基礎庫版本 1.5.0 起,觸控類事件支援捕獲階段。捕獲階段位於冒泡階段之前,且在捕獲階段中,事件到達節點的順序與冒泡階段恰好相反。需要在捕獲階段監聽事件時,可以採用capture-bind
、capture-catch
關鍵字,後者將中斷捕獲階段和取消冒泡階段。
在下面的程式碼中,點選 inner view 會先後呼叫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>
如果將上面程式碼中的第一個capture-bind改為capture-catch,將只觸發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>
事件物件
如無特殊說明,當元件觸發事件時,邏輯層繫結該事件的處理函式會收到一個事件物件。
BaseEvent 基礎事件物件屬性列表:
屬性 | 型別 | 說明 |
---|---|---|
type | String | 事件型別 |
timeStamp | Integer | 事件生成時的時間戳 |
target | Object | 觸發事件的元件的一些屬性值集合 |
currentTarget | Object | 當前元件的一些屬性值集合 |
CustomEvent 自定義事件物件屬性列表(繼承 BaseEvent):
屬性 | 型別 | 說明 |
---|---|---|
detail | Object | 額外的資訊 |
TouchEvent 觸控事件物件屬性列表(繼承 BaseEvent):
屬性 | 型別 | 說明 |
---|---|---|
touches | Array | 觸控事件,當前停留在螢幕中的觸控點資訊的陣列 |
changedTouches | Array | 觸控事件,當前變化的觸控點資訊的陣列 |
特殊事件: <canvas>
中的觸控事件不可冒泡,所以沒有 currentTarget。
type
代表事件的型別。
timeStamp
頁面開啟到觸發事件所經過的毫秒數。
target
觸發事件的源元件。
屬性 | 型別 | 說明 |
---|---|---|
id | String | 事件源元件的id |
tagName | String | 當前元件的型別 |
dataset | Object | 事件源元件上由data- 開頭的自定義屬性組成的集合 |
currentTarget
事件繫結的當前元件。
屬性 | 型別 | 說明 |
---|---|---|
id | String | 當前元件的id |
tagName | String | 當前元件的型別 |
dataset | Object | 當前元件上由data- 開頭的自定義屬性組成的集合 |
說明: target 和 currentTarget 可以參考上例中,點選 inner view 時,handleTap3
收到的事件物件 target 和 currentTarget 都是 inner,而handleTap2
收到的事件物件 target 就是 inner,currentTarget 就是 middle。
dataset
在元件中可以定義資料,這些資料將會通過事件傳遞給 SERVICE。 書寫方式: 以data-開頭,多個單詞由連字元-連結,不能有大寫(大寫會自動轉成小寫)如data-element-type,最終在 event.currentTarget.dataset 中會將連字元轉成駝峰elementType。
示例:
<view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view>
Page({
bindViewTap:function(event){
event.currentTarget.dataset.alphaBeta === 1 // - 會轉為駝峰寫法
event.currentTarget.dataset.alphabeta === 2 // 大寫會轉為小寫
}
})
touches
touches 是一個陣列,每個元素為一個 Touch 物件(canvas 觸控事件中攜帶的 touches 是 CanvasTouch 陣列)。 表示當前停留在螢幕上的觸控點。
Touch 物件
屬性 | 型別 | 說明 |
---|---|---|
identifier | Number | 觸控點的識別符號 |
pageX, pageY | Number | 距離文件左上角的距離,文件的左上角為原點 ,橫向為X軸,縱向為Y軸 |
clientX, clientY | Number | 距離頁面可顯示區域(螢幕除去導航條)左上角距離,橫向為X軸,縱向為Y軸 |
CanvasTouch 物件
屬性 | 型別 | 說明 |
---|---|---|
identifier | Number | 觸控點的識別符號 |
x, y | Number | 距離 Canvas 左上角的距離,Canvas 的左上角為原點 ,橫向為X軸,縱向為Y軸 |
changedTouches
changedTouches 資料格式同 touches。 表示有變化的觸控點,如從無變有(touchstart),位置變化(touchmove),從有變無(touchend、touchcancel)。
detail
自定義事件所攜帶的資料,如表單元件的提交事件會攜帶使用者的輸入,媒體的錯誤事件會攜帶錯誤資訊,詳見元件定義中各個事件的定義。
點選事件的detail
帶有的 x, y 同 pageX, pageY 代表距離文件左上角的距離。
相關文章
- 小程式選人控制元件 – 仿企業微信實現多選及多層級無規則巢狀控制元件巢狀
- 小程式選人控制元件 - 仿企業微信實現多選及多層級無規則巢狀控制元件巢狀
- 微信小程式自定義tab,多層tab巢狀實現微信小程式巢狀
- jQuery如何阻止事件冒泡jQuery事件
- 原生js如何阻止事件冒泡JS事件
- javascript阻止事件冒泡程式碼JavaScript事件
- JavaScript阻止事件冒泡JavaScript事件
- jquery阻止事件冒泡jQuery事件
- 微信小程式入門教程--列表渲染多層巢狀迴圈及wx:key的使用微信小程式巢狀
- Swift UITableView巢狀UICollectionView點選事件衝突(點選事件穿透)SwiftUIView巢狀事件穿透
- JavaScript 阻止事件冒泡程式碼例項JavaScript事件
- js阻止事件冒泡例項程式碼JS事件
- jQuery阻止事件冒泡程式碼例項jQuery事件
- 阻止jquery事件冒泡程式碼例項jQuery事件
- jQuery阻止事件冒泡例項程式碼jQuery事件
- 漫談 React 元件庫開發(一):多層巢狀彈層元件React元件巢狀
- stopPropagation() 阻止事件冒泡事件
- 集合框架-集合的巢狀遍歷(多層巢狀)框架巢狀
- 相容所有瀏覽器的阻止事件冒泡程式碼瀏覽器事件
- 阻止冒泡和阻止預設事件的相容寫法事件
- jQuery阻止事件冒泡現象程式碼例項jQuery事件
- 多層巢狀同義詞巢狀
- 相容所有瀏覽器的阻止事件冒泡js程式碼瀏覽器事件JS
- 前端學習程式碼例項-JavaScript阻止事件冒泡前端JavaScript事件
- jQuery阻止事件冒泡和預設行為程式碼jQuery事件
- 多層巢狀表型別語法巢狀型別
- JavaScript事件冒泡、事件捕獲和阻止預設事件JavaScript事件
- jQuery阻止事件冒泡簡單介紹jQuery事件
- 原生javascript的return false並不能阻止事件冒泡JavaScriptFalse事件
- 微信小程式如何響應使用者點選事件和微信平臺 API 的使用方法介紹微信小程式事件API
- 微信小程式實現點贊、取消點贊,和多項點選功能微信小程式
- 相容所有瀏覽器的阻止事件冒泡封裝瀏覽器事件封裝
- vue elementUI 表單校驗(多層巢狀)VueUI巢狀
- 相容低版本IE瀏覽器的阻止事件冒泡效果程式碼瀏覽器事件
- 微信小程式下拉選單自定義元件微信小程式元件
- 微信小程式自定義元件-城市選擇微信小程式元件
- 小程式如何避免多次點選,重複觸發事件事件
- 多層巢狀後的 Fragment 懶載入實現巢狀Fragment