creator RichText组件 click标签回调路径的问题

RichText组件为我们提供了强大的富文本功能,但是在使用的过程中发现必须在富文本节点挂上一个脚本,所有的点击事件会在富文本所在节点上触发,但是做游戏的过程中我们的富文本可能只是整个ui界面中一个节点,所有的ui逻辑可能会在其他脚本上触发,例如我们会在整个ui上加一个脚本来管理ui所有子节点,这就导致富文本的点击在ui脚本上无法触发

图中的handler2只能在RichText组件所在的节点脚本上触发,定义在其他脚本是无法触发,这就很难受了,同时笔者也在想RichText内部是怎么实现的,为什么会有这样的限制,而Node自带的click属性却是可以直接指定调用的脚本组件,不需要我们为button所在的节点单独挂一个脚本

我们传入脚本的this,便可以直接在脚本中处理回调,但是,RichText却不行,必须要在RichText脚本组件上挂一个脚本,然后在里面写上点击的回调方法,这可不是一个好主意,如果每个界面都要有一个RichText,那……本着研究(偷懒)的精神,笔者去查看RichText组件的源码,终于发现了罪魁祸首:

组件中接手了touch事件,笔者兴奋了,应该就是这里

笔者看到第一句!!!心想大事不妙,果然RichText是拿的组件节点上的脚本组件,this._labelSegments应该是富文本是RichText创建的每一个label,clickHandler就是我们定义的点击事件名,也就是脚本中的回调方法名,clickParam便是我们定义的方法参数。

怎么办?改源码?让我们可以指定节点进去,然后在指定节点派发事件,这是一个好办法,说干就干,不行,改了还要从新编译迎请戴拿,这次改了引擎更新怎么办?本着不动引擎(偷懒)的精神,笔者决定换一种思路。

既然必须在richText节点加脚本,加就完事了
但是我们仍然想在ui脚本上触发事件怎么办?将方法回调在richText脚本的组件上定义一份,然后再ui脚本上定义一次,最后在richtext节点脚本的回调里再回调回ui脚本?

就这么办,好像要写两个方法,不划算(偷懒),但是我们有Object.defineProperty这个东东

这就很明白了,首先我们需要建立一个脚本挂在richText组件的节点上,RichTextEvent
`RichTextEvent = cc.Class({
extends:cc.Component,
properties: {
_RichText:null,
_object:null,
},

setObject(Object){
    this._object = Object;
},

onLoad(){
    
},
start(){
    this._RichText = this.node.getComponent(cc.RichText);

    let _labelSegments = this._RichText._labelSegments;
    for (let i = 0; i < _labelSegments.length; ++i) {
        let labelSegment = _labelSegments[i];
        let clickHandler = labelSegment._clickHandler;
        let clickParam = labelSegment._clickParam;
        
        Object.defineProperty(this,clickHandler,{
            __proto__: null,
            enumerable: false,
            configurable: false,
            writable: true,
            value:function(event,clickParam){
                if(this._object&&this._object[clickHandler]){
                    this._object[clickHandler](event,clickParam);
                }
            }
        });
    }
},

onDestroy(){
    if(this._object){
        this._object = null;
    }
}`

在start中,我们获取RichText组件,紧接着获取组件中的_labelSegments列表,我们可以从里面获取每一个点击事件加参数,然后通过Object.defineProperty自动给脚本定义回调方法,在回调方法中,我们反过来回调到我们需要的脚本当中

再建立一个方法,动态给每一个需要的RichText组件添加RichTextEvent

ok大功告成,在需要处理的脚本当中,我们只需要

给RichText赋值之后,我们只需要调用一下之前定义的全局方法即可,然后就可以愉快的在当前脚本中添加回调事件了
结果:

一切都如我们想的这般美好!!!

4赞

有没有可能这么些就好了,简单粗暴

 this._RichText["onRichTextHandler"] = function (ev: EventTouch, prama) {

            console.info("点击了富文本链接:", prama)

        };
2赞

I like