creator点击事件分为触摸:鼠标点击其中鼠标点击事件只有在桌面平台才会触发,触摸事件在移动平台和桌面平台都会触发,所以如果是需要发布移动平台(安卓,ios)的朋友点击事件只能监听触摸事件!
官方点击事件文档:http://docs.cocos.com/creator/manual/zh/scripting/internal-events.html
封装点击事件代码:
const {ccclass, property} = cc._decorator;
/**
* 按钮事件监听
*/
@ccclass
export default class UIEventListener extends cc.Component
{
/**
* 当鼠标在目标节点在目标节点区域中移动时,不论是否按下
*/
public mouseMove: (event: any) => void;
/**
* 当鼠标移入目标节点区域时,不论是否按下
*/
public mouseEnter: (event: any) => void;
/**
* 当鼠标移出目标节点区域时,不论是否按下
*/
public mouseLeave: (event: any) => void;
/**
* 当鼠标从按下状态松开时触发一次
*/
public mouseUp: (event: any) => void;
start ()
{
this.addEvents();
}
private addEvents():void
{
this.node.on<cc.Event.EventTouch|cc.Event.EventMouse|cc.Event.EventCustom>(cc.Node.EventType.TOUCH_START,this.onMouseEnter,this);
this.node.on<cc.Event.EventTouch|cc.Event.EventMouse|cc.Event.EventCustom>(cc.Node.EventType.TOUCH_MOVE,this.onMouseMove,this);
this.node.on<cc.Event.EventTouch|cc.Event.EventMouse|cc.Event.EventCustom>(cc.Node.EventType.TOUCH_END,this.onMouseUp,this);
this.node.on<cc.Event.EventTouch|cc.Event.EventMouse|cc.Event.EventCustom>(cc.Node.EventType.TOUCH_CANCEL,this.onMouseLeave,this);
}
public onDestroy():void
{
this.removeEvents();
}
private removeEvents():void
{
this.mouseLeave = null;
this.mouseEnter = null;
this.mouseMove = null;
this.mouseUp = null;
this.node.off(cc.Node.EventType.TOUCH_START,this.onMouseEnter,this);
this.node.off(cc.Node.EventType.TOUCH_MOVE,this.onMouseMove,this);
this.node.off(cc.Node.EventType.TOUCH_END,this.onMouseUp,this);
this.node.off(cc.Node.EventType.TOUCH_CANCEL,this.onMouseLeave,this);
}
private onMouseMove(event:cc.Event):void
{
if (this.mouseMove != null)
{
this.mouseMove(event);
}
}
private onMouseEnter(event:cc.Event):void
{
if (this.mouseEnter != null)
{
this.mouseEnter(event);
}
}
private onMouseLeave(event:cc.Event):void
{
if (this.mouseLeave != null)
{
this.mouseLeave(event);
}
}
private onMouseUp(event:cc.Event):void
{
if (this.mouseUp != null)
{
this.mouseUp(event);
}
}
public static Get(node:cc.Node):UIEventListener
{
let listener:UIEventListener = node.getComponent(UIEventListener);
if (listener == null) {
listener = node.addComponent(UIEventListener);
}
return listener;
}
}
使用示例:
let uiEventListener = UIEventListener.Get(this.node);
uiEventListener.mouseUp = this.onMouseUp.bind(this);
private onMouseUp(event:cc.Event):void
{
//dosomething
//event.stopPropagation(); 可以停止冒泡传递
}
//释放点击事件
uiEventListener.mouseUp = null
注意点: 点击事件有增就有减,需要配套使用,当其中一个对象需要被释放的时候,该对象的点击事件也需要同时被释放,如果不释放的话该对象会释放不了。
关于事件冒泡:
有点类似与点击穿透,但又不是点击穿透。简单的理解为:按钮点击的行为会从当前节点往父节点循环传递,一般情况下我们都是不需要传递的,
使用unity的ugui的开发者有一些喜欢在父级gameObject添加点击事件,如果你在子物体上也添加了点击事件,子物体与父级有相交,点击子物体的时候,如果不主动停止冒泡的话同时也会触发父级的点击事件
官方的解释如下:
在图中的场景里,A节点拥有一个子节点B,B拥有一个子节点C。假设开发者对A、B、C都监听了触摸事件。当鼠标或手指在B节点区域内按下时,事件将首先在B节点触发,B节点监听器接收到事件。接着B节点会将事件向其父节点传递这个事件,A节点的监听器将会接收到事件。这就是最基本的事件冒泡过程。
当鼠标或手指在C节点区域内按下时,事件将首先在C节点触发并通知C节点上注册的事件监听器。C节点会通知B节点这个事件,B节点内逻辑会负责检查触点是否发生在自身区域内,如果是则通知自己的监听器,否则什么都不做。紧接着A节点会收到事件,由于C节点完整处在A节点中,所以注册在A节点上的事件监听器都将收到触摸按下事件。以上的过程解释了事件冒泡的过程和根据节点区域来判断是否分发事件的逻辑。
除了根据节点区域来判断是否分发事件外,触摸事件的冒泡过程与普通事件的冒泡过程并没有区别。所以,调用 event 的 stopPropagation 函数可以主动停止冒泡过程。
防止点击穿透:
在node上添加cc.BlockInputEvents 组件:添加组件>添加ui组件>BlockInputEvents