# Event

# What Is an Event?

  • An event is a channel through which the view layer communicants with the logical layer.
  • An event can pass user's action on to the logical layer for processing.
  • An event can be bound to a component. When the event is triggered, the corresponding event handler is executed at the logic layer.
  • An event object can have additional information such as ID, dataset, touches.

# How to Use an Event

  • Bind an event handler to the component.

For example, if the event is bindtap, the event handler can be found in the page when a user taps the component.

<view id="tapTest" data-hi="Weixin" bindtap="tapName"> Click me! </view>
  • Write the event handler in the Page definition with "event" as the parameter.
Page({
  tapName: function(event) {
    console.log(event)
  }
})
  • The log content is as follows:
{
  "type":"tap",
  "timeStamp":895,
  "target": {
    "id": "tapTest",
    "dataset":  {
      "hi":"Weixin"
    }
  },
  "currentTarget":  {
    "id": "tapTest",
    "dataset": {
      "hi":"Weixin"
    }
  },
  "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
  }]
}

# Respond to Events with WXS Function

Start from base library version 2.4.4. Please remaining backward compatible.

As of base library version 2.4.4, you can bind events using the WXS function, which accepts two parameters. One is "event", with an additional event.instance object. The other is ownerInstance, which is a ComponentDescriptor object, just like event.instance. The WXS function is used as follows:

  • Bind and register the WXS function for event handling in component.
<wxs module="wxs" src="./test.wxs"></wxs>
<view id="tapTest" data-hi="Weixin" bindtap="{{wxs.tapName}}"> Click me! </view>
**Note: The bound WXS function must be enclosed with {{}}.**

  • Test.wxs file implements the tapName function.
function tapName(event, ownerInstance) {
  console.log('tap Weixin', JSON.stringify(event))
}
module.exports = {
  tapName: tapName
}

ownerInstance contains some methods to set the style and class of a component. For more information on the methods and the reason why the WXS function is used to response to events, click here.

# Events

# Event Types

Events are divided into bubbling events and non-bubbling ones.

  1. Bubbling event: When an event is triggered on a component, this event is propagated to the component's parent node.
  2. Non-bubbling event: When an event is triggered on a component, this event is not propagated to the component's parent node.

WXML bubbling events:

Type Trigger Condition Minimum Version
touchstart Finger touch starts
touchmove Finger moves after touch
touchcancel Finger touch is interrupted by call reminder, pop-up window, etc.
touchend Finger touch ends
tap The finger leaves the screen after touch
longpress The finger leaves the screen after it taps and holds on the screen for more than 350 ms. If an event callback function is specified and this event is triggered, the tap event is not triggered. 1.5.0
longtap The finger leaves the screen after it taps and holds on the screen for more than 350 ms (it is recommended to use longpress event instead).
transitionend Triggered when a WXSS transition or wx.createAnimation animation ends
animationstart Triggered when a WXSS animation starts
animationiteration Triggered after an iteration of a WXSS animation ends
animationend Triggered when a WXSS animation completes
touchforcechange Triggered when the screen is tapped again on an iPhone supporting 3D Touch. 1.9.90

Note: Unless otherwise specified, the custom events of components other than those listed above are non-bubbling events, such as the submit event of [form]((form), input event of [input]((input), and scroll event of [scroll-view]((scroll-view). For more information, see Components).

# Event Binding and Bubbling

Similar to component properties, an event is bound in the form of key and value.

  • Key starts with bind or catch, followed by the event type, such as bindtap and catchtouchstart. As of base library version 1.5.0, in non-[native-component] (../../../component/native-component.md), bind and catch can be followed by a colon with their meaning remaining unchanged.
  • Value is a string, and a function with the same name needs to be defined in the Page. Otherwise, an error will occur when the event is triggered.

Binding bind event does not prevent a bubbling event from bubbling, but binding catch event does.

In the example shown below, tap "inner view" to call handleTap3 and handleTap2 (because the tap event is propagated to middle view, which prevents the tap event from being propagated to the parent node); tap "middle view" to trigger handleTap2 and tap "outer view" to trigger 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>

# Event Capturing

As of base library 1.5.0, touch-related events support capturing. In event capturing, which precedes bubbling, events arrive at nodes in an order reverse of that in which they do during bubbling. To listen to events during capturing, use capture-bind or capture-catch as the keyword. The latter interrupts the capturing and cancels bubbling.

In the code below, tap "inner view" to call handleTap2, handleTap4, handleTap3, and handleTap1 in turn.

<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>

If the first capture-bind in the above code is changed to capture-catch, only handleTap2 is triggered.

<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>

# Event Objects

Unless otherwise specified, when the component triggers an event, the handler bound to the event at logic layer receives an event object.

BaseEvent object properties:

Property Type Description Base Library Version
type String Event Type
timeStamp Integer Timestamp when the event is generated
target Object A collection of property values​for the component triggering the event
currentTarget Object A collection of property values​for the current component
mark Object Event flag data 2.7.1

CustomEvent object properties (inherit from BaseEvent):

Property Type Description
detail Object Additional information

TouchEvent object properties (inherit from BaseEvent):

Property Type Description
touches Array Touch event. An array of information of touch points staying in the screen.
changedTouches Array Touch event. An array of information of touch points involving changes in the screen

Special events: The touch events in canvas are non-bubbling events and thus have no currentTarget.

# type

Represents the type of an event.

# timeStamp

Number of milliseconds from the moment when the page is opened until the event is triggered.

# target

The source component triggering the event.

Property Type Description
id String ID of the event source component
tagName String Type of the current component
dataset Object A collection of custom properties starting with data- on the event source component

# currentTarget

The current component bound to the event.

Property Type Description
id String Current component ID
tagName String Type of the current component
dataset Object A collection of custom properties starting with data- on the current component

Note: You can refer to the above example for "target" and "currentTarget". When you tap "inner view", the event objects "target" and "currentTarget" received by handleTap3 are both "inner", but the "target" and "currentTarget" received by handleTap2 are "inner" and "middle", respectively.

# dataset

You can add some custom data to the component node so as to obtain the custom node data from the event for logical processing.

In WXML, these custom data begins with data- and multiple words are joined with hyphen -. In the code, a hyphenation is converted to camel case, and the uppercase characters are automatically converted to lowercase ones. For example:

  • data-element-type is converted to event.currentTarget.dataset.elementType;
  • data-elementType is converted to event.currentTarget.dataset.elementtype.

Example:

<view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view>
Page({
  bindViewTap:function(event){
    event.currentTarget.dataset.alphaBeta === 1 // - Converts to camel case
    event.currentTarget.dataset.alphabeta === 2 // Uppercase converts to lowercase
  }
})

# mark

As of base library 2.7.1, you can use mark to identify the target node triggering the event. In addition, mark can also be used to carry some custom data (similar to dataset).

When an event is triggered, all marks on the event bubbling path are merged and returned to the event callback function. (Even if the event is not a bubbling event, mark is called.)

Code example:

Preview with Developer Tool

<view mark:myMark="last" bindtap="bindViewTap">
  <button mark:anotherMark="leaf" bindtap="bindButtonTap">Button</button>
</view>

In the above WXML, if a button is tapped, events bindViewTap and bindButtonTap are triggered. The event.mark carried by the event contains myMark and anotherMark.

Page({
  bindViewTap: function(e) {
    e.mark.myMark === "last" // true
    e.mark.anotherMark === "leaf" // true
  }
})

mark is very similar to dataset, except that mark contains all the mark: property values from the event-triggering node to the root node, while dataset only contains the data- property value of one node.

Notes:

  • If there are duplicate marks with the same name, the mark at the parent node is overwritten by that at the child node.
  • When an event is received in a custom component, mark does not contain the mark of the node outside the custom component.
  • Unlike dataset, mark at the node does not involve hyphenation and case conversion.

# touches

"touches" is an array, in which each element is a Touch object ("touches" in the canvas touch event is a CanvasTouch array). Touch points staying in the screen

# Touch objects

Property Type Description
identifier Number Touch point identifier
pageX, pageY Number Distance from the upper left corner of the document. The top left corner is the origin, the horizontal line is X-axis, and the vertical line is Y-axis.
clientX, clientY Number Distance from the upper left corner of the page display area (the area on the screen without navigation pane). The horizontal line is X-axis and the vertical line is Y-axis.

# CanvasTouch objects

Property Type Description Comment
identifier Number Touch point identifier
x, y Number Distance from the upper left corner of Canvas. Canvas's upper left corner is the origin, the horizontal line is X-axis, and the vertical line is Y-axis.

# changedTouches

Indicates the touch points involving changes (in the same format as "touches"), including touchstart (appearance of touch point), touchmove (movement of touch point), and touchend/touchcancel (disappearance of touch point).

# detail

The data carried by the custom event. For example, the submission event of a form component carries user's input, and the error event of media carries the error message. For more information, see the event definitions in Components.

Similar to pageX and page Y, the x and y in detail of the tap event represent the distance from the upper left corner of the document.