用户:
Nomen查看:0 回复:4 评论:0 创建时间:2024-03-24T10:34:38
这是一个未经完整测试的工具,用于根据css查找式查找元素,目前暂不支持多重条件
注:无法将该工具导出到本体所在上下文,建议使用多模块或上下文管理
例子:
const { require } = requireFrom();
const { UiBox } = require("./query.js");
let b1 = UiBox.create(), b2 = UiBox.create(), b3 = UiBox.create();
b1.parent = ui;
b2.parent = b1;
b3.parent = b2;
b2.classList = ["class1", "class2"];
b3.name = "nameB3";
b3.attributes = {
"key1": "value1"
};
console.log(b1.querySelectorAll(".class1"));
console.log(b1.querySelectorAll(".class1.class2"));
console.log(b1.querySelectorAll("#nameB3"));
console.log(b1.querySelectorAll("[key1=value1]"));
function requireFrom(_ = {
"./query.js": function() {
/* query.js */
},
}) {
/* require.js */
}
本体:
/* eslint-disable no-unused-vars */
/* eslint-disable no-undef */
/* eslint-disable indent */
function Query() {
function tokenize(selector) {
const regex = /([.#]?[\w-]+|\*|>|\[.+?\])|\s+/g;
const tokens = [];
let match;
while ((match = regex.exec(selector)) !== null) {
const token = match[0];
if (token === ">") {
if (tokens.length > 0 && tokens[tokens.length - 1].type === "descendant") {
tokens.pop();
}
tokens.push({ type: "child" });
} else if (token.trim() === "") {
if (tokens.length > 0 && tokens[tokens.length - 1].type !== "descendant") {
tokens.push({ type: "descendant" });
}
} else if (token.startsWith(".")) {
tokens.push({ type: "class", value: token.slice(1) });
} else if (token.startsWith("#")) {
tokens.push({ type: "id", value: token.slice(1) });
} else if (token.startsWith("[")) {
const attribute = token.slice(1, -1).split(/,(?=(?:[^"]*"[^"]*")*[^"]*$)/g).map((attr) => {
const [key, value] = attr.split(/=(?=(?:[^"]*"[^"]*")*[^"]*$)/g);
return { key, value };
});
tokens.push({ type: "attribute", value: attribute });
} else {
tokens.push({ type: "tag", value: token });
}
}
return tokens;
}
function parse(tokens) {
let node = {
type: "node",
child: null,
needDriectChild: false,
filter: []
};
for (let i = 0; i < tokens.length; i++) {
let token = tokens[i];
if (["id", "class", "tag", "attribute"].includes(token.type)) {
node.filter.push(token);
} else if (token.type === "child") {
node.needDriectChild = true;
} else if (token.type === "descendant") {
let child = parse(tokens.slice(i + 1));
node.child = child;
break;
} else {
throw new Error("Unknow token type");
}
}
return node;
}
const root = ui;
function filter(obj, filters) {
let res = true;
filters.forEach(v => {
if (!res) return;
if (v.type === "tag") {
let r = {
"box": UiBox,
"text": UiText,
"image": UiImage
};
if (!(obj instanceof r[v.value])) {
res = false;
}
} else if (v.type === "id") {
if (obj.name !== v.value) {
res = false;
}
} else if (v.type === "class") {
if (!obj.classList?.includes(v.value)) {
res = false;
}
} else if (v.type === "attribute") {
let attr = obj.attributes;
if(attr) v.value.forEach(a => {
if (attr[a.key] !== a.value) {
res = false;
}
});
}
});
return res;
}
function querySelectorAll(selector) {
let tree;
if (typeof selector === "string") {
tree = parse(tokenize(selector));
} else {
tree = selector;
}
let result = [];
const traverseChildren = (node) => {
if (node.children) {
node.children.forEach(child => {
if (filter(child, tree.filter)) {
result.push(child);
}
traverseChildren(child);
});
}
};
traverseChildren(this);
return result;
}
function querySelector(selector) {
return this.querySelectorAll(selector)[0];
}
function _createClass(Ui) {
return class __class_constructor__ {
static create(...args) {
const instance = new __class_constructor__(...args);
return new Proxy(instance, {
get(target, prop, receiver) {
if (prop in target) return Reflect.get(target, prop, receiver);
else return Reflect.get(target.__node, prop, receiver);
},
set(target, prop, value, receiver) {
if (prop in target) return Reflect.set(target, prop, value, receiver);
else return Reflect.set(target.__node, prop, value, receiver);
}
});
}
constructor(...args) {
this.__node = Ui.create(...args);
this._children = [];
}
get children() { return this._children; }
set parent(p) { this.__node.parent = p.__node || p; p._children?.push(this); }
get parent() { return this.__node.parent; }
querySelectorAll(selector) { return querySelectorAll.call(this, selector); }
querySelector(selector) { return querySelector.call(this, selector); }
};
}
const __UiBox = _createClass(UiBox);
const __UiText = _createClass(UiText);
const __UiImage = _createClass(UiImage);
(function _init(parent = root) {
parent.querySelectorAll = querySelectorAll.bind(parent);
parent.querySelector = querySelector.bind(parent);
parent.children.forEach(child => _init(child));
})();
return {
querySelectorAll,
querySelector,
UiBox: __UiBox,
UiText: __UiText,
UiImage: __UiImage
};
}
时当日色QWQimgsrc="https://static.codemao.cn/emoji/codemao/%E7%BC%96%E7%A8%8B%E7%8C%AB_%E5%8A%A0%E6%B2%B9.gif"alt="emotion_编程猫_加油"
点赞0
评论