工作随想
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 = 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赋值之后,我们只需要调用一下之前定义的全局方法即可,然后就可以愉快的在当前脚本中添加回调事件了 结果:


最后修改于 2022-07-13