// Learn TypeScript: // - https://docs.cocos.com/creator/manual/en/scripting/typescript.html // Learn Attribute: // - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html // Learn life-cycle callbacks: // - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html const {ccclass, property} = cc._decorator; @ccclass export default class Attributes extends cc.Component { @property id: string = ''; @property class: string = ''; @property({ type: [cc.String], displayName: '自定义属性', tooltip: "key:value结构,冒号“:”分割" }) customAttributeStrArr: string[] = []; attrMap = {}; // LIFE-CYCLE CALLBACKS: // onLoad () {} start () { this.attrMap = {} for (let i = 0 ; i < this.customAttributeStrArr.length; i++) { const att = this.customAttributeStrArr[i]; const [k, v] = att.split(':'); this.attrMap[k] = v; } } checkNode({selector, type, node, first = true, result = []}) { // console.log(node.name); const att = node.getComponent('Attributes'); if (att && att[type] === selector ) { if (first) { return node; } else { result.push(node); att.walkChildren({selector, type, node, first, result}) } } else if(att && type === 'attr') { let [k ,v] = selector.split('='); if (k) { k = k.trim() } if (v) { v = v.trim() } if (k && !v) { if (first) { if(k in att.attrMap) { return node; } } else { if(k in att.attrMap) { result.push(node); } att.walkChildren({selector, type, node, first, result}) } } else if (k && v){ if (first) { if(att.attrMap[k]==v) { return node; } } else { if(att.attrMap[k]==v) { result.push(node); } att.walkChildren({selector, type, node, first, result}) } } } else { if (first) { const matchNode = this.walkChildren({selector, type, node, first, result}); if (matchNode) { return matchNode } } else { this.walkChildren({selector, type, node, first, result}); } } } walkChildren({selector, type, node, first = true, result = []}) { for (let i = 0; i < node.children.length; i++) { const n = node.children[i]; // console.log(n.name); const r = this.checkNode({selector, type, node: n, first, result}); if (first && r) { return r; } } } walk({selector, type, node, first = true, result = []}) { const r = this.checkNode({selector, type, node, first, result}); if (first && r) { return r; } } getToken(selector) { const s = selector[0]; let type = 'name'; selector = selector.substr(1); if (s === '.') { type = 'class'; } else if (s === '#') { type = 'id' } else if (s === '[') { type = 'attr' selector = selector.substring(0, selector.length-1); selector = selector.replace(/\s+/g, '').replace(/'/g, '').replace(/"/g, ''); } else { selector = s + selector; } return { type, selector } } querySelector(selectorStr) { const {selector, type} = this.getToken(selectorStr); return this.walk({selector, type, node: this.node}); } querySelectorAll(selectorStr) { const {selector, type} = this.getToken(selectorStr); const result = []; this.walk({selector, type, node: this.node, first: false, result}); return result; } // update (dt) {} }