Listening to and launching events

Listening to events

Event processing is done in the Node. Components can register and monitor events by visiting the node this.node. Listen to events can be registered by the function this.node.on(). The methods are as follows:

  1. // This event monitor is triggered every time and needs to be unregistered manually.
  2. xxx.on(type, func, target?);

The type is the event registration string. func is the callback to listen to when the event is executed. And target is the event receive object. If target is not set, then this in the callback refers to the object that is currently executing the callback.

The event listener function on can pass to the third parameter target to bind the caller of the response function. The following two calling methods have the same effect:

  1. // Using Function Binding
  2. this.node.on(Node.EventType.MOUSE_DOWN, function ( event ) {
  3. this.enabled = false;
  4. }.bind(this));
  5. // Using the third parameter
  6. this.node.on(Node.EventType.MOUSE_DOWN, (event) => {
  7. this.enabled = false;
  8. }, this);

Besides listening with on, we can also use the once method. The once listener will shut the event being listened to after the listener function responds.

Canceling listeners

We can shut the corresponding event listener using off when we don’t care about a certain event anymore.

The off method can be used in two ways

  1. // Cancel all registered events of this type on the object.
  2. xxx.off(type);
  3. // Cancels events on objects with this type of callback designation target.
  4. xxx.off(type, func, target);

One thing to note is that the parameter of off must be in one-to-one correspondence with the parameter of on in order to cancel it.

Example:

  1. import { _decorator, Component, Node } from 'cc';
  2. const { ccclass } = _decorator;
  3. @ccclass("Example")
  4. export class Example extends Component {
  5. onEnable () {
  6. this.node.on('foobar', this._sayHello, this);
  7. }
  8. onDisable () {
  9. this.node.off('foobar', this._sayHello, this);
  10. }
  11. _sayHello () {
  12. console.log('Hello World');
  13. }
  14. }

Event Dispatching

There are two ways to trigger an event: emit and dispatchEvent. The difference between the two is that the latter can do event passing. Let’s start with a simple example of the emit event.

  1. // At most 5 args could be emit.
  2. xxx.emit(type, ...args);

Explanation for event arguments

When emitting events, start passing the event parameters as the second argument of the emit function.

  1. import { _decorator, Component, Node } from 'cc';
  2. const { ccclass } = _decorator;
  3. @ccclass("Example")
  4. export class Example extends Component {
  5. onLoad () {
  6. this.node.on('foo', (arg1, arg2, arg3) => {
  7. console.log(arg1, arg2, arg3); // print 1, 2, 3
  8. });
  9. }
  10. start () {
  11. let arg1 = 1, arg2 = 2, arg3 = 3;
  12. // At most 5 args could be emit.
  13. this.node.emit('foo', arg1, arg2, arg3);
  14. }
  15. }

Note: only up to 5 event parameters can be passed here for the performance of the underlying event distribution. Therefore, care should be taken to control the number of parameters passed when passing a parameter.

Event delivery

Events launched by the dispatchEvent method, mentioned above, would enter the event delivery stage. In Cocos Creator‘s event delivery system, bubble delivery is used. Bubble delivery will pass the event from the initiating node continually on to its parent node, until the root node is reached or an interrupt event.propagationStopped = true is made in the response function of a node.

In v3.0, we removed the Event.EventCustom class. To dispatch custom events, a custom event class that inherits from the Event class needs to be implemented first. For example:

  1. // Import "Event" from 'cc' module
  2. import { Event } from 'cc';
  3. class MyEvent extends Event {
  4. constructor(name: string, bubbles?: boolean, detail?: any){
  5. super(name, bubbles);
  6. this.detail = detail;
  7. }
  8. public detail: any = null; // Custom property
  9. }

bubble-event

As shown in the picture above, when we send the event “foobar” from node c, if both node a and b listen to the event “foobar”, the event will pass to node b and a from c. For example:

  1. // In the component script of node c
  2. this.node.dispatchEvent( new MyEvent('foobar', true, 'detail info') );

To stop the event delivery after node b intercepts the event, call the function event.propagationStopped = true to do this. Detailed methods are as follows:

  1. // In the component script of node b
  2. this.node.on('foobar', (event: MyEvent) => {
  3. event.propagationStopped = true;
  4. });

Note: to dispatch a custom event, do not use Event directly because it’s an abstract class.

Event object

In the call-back of the event listener, the developer will receive an event object event of the Event type. propagationStopped is the standard API of Event, other important API include:

API NameTypeMeaning
typeStringThe event type (event name).
targetNodeThe original target that received the event.
currentTargetNodeThe current object that received the event. The current target of the event during the bubbling phase may be different from the original target.
getTypeFunctionGet the event type.
propagationStoppedBooleanWhether or not stop the bubbling phase. The parent node of the current target no longer receives the corresponding event.
propagationImmediateStoppedBooleanWhether or not stop passing the current event immediately. The current target no longer receives the event either.

Please refer to the Event and API files of its child category for a complete API list.

System built-in event

Above are the general rules for listening to events and emitting events. Cocos Creator has built in system events. Please refer to the following documents: