Skip to content

Commit 4feb0e3

Browse files
committed
ControlNode类,用于控制节点
1 parent 90f5b9d commit 4feb0e3

1 file changed

Lines changed: 367 additions & 0 deletions

File tree

Lines changed: 367 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,367 @@
1+
/*
2+
* @Date: 2020-04-29 10:13:23
3+
* @LastEditors : MemoryShadow
4+
* @LastEditTime : 2021-01-06 20:13:22
5+
* @Effect: 内置类ControlNode,用于控制节点,并包含一些内置的控件,可以快速创建
6+
*/
7+
8+
/**
9+
* 节点控制器
10+
*/
11+
12+
function ControlNode(MainNodeID) {
13+
14+
/**
15+
* 储存对象名称"ID"
16+
*/
17+
this.Name;
18+
19+
/**
20+
* 储存主节点
21+
*/
22+
this.MainNodeObject;
23+
24+
/**
25+
* RegisteredNode自动维护的输入框对象表,用于追踪目标对象
26+
*/
27+
this.Node_Data_List = [];
28+
29+
/**
30+
* 此对象在公共队列中的位置
31+
*/
32+
this.thisObjectIndex;
33+
34+
/**
35+
* 构造器
36+
* @param {string} MainNodeID 指定要作为主节点的ID
37+
*/
38+
this.constructor = function (MainNodeID) {
39+
this.MainNodeObject = document.getElementById(MainNodeID);
40+
// 储存自己的名字(ID)
41+
this.Name = MainNodeID;
42+
// 在添加前储存索引
43+
this.thisObjectIndex = ControlNode.ObjectList.length;
44+
ControlNode.ObjectList.push(this);
45+
}
46+
47+
/**
48+
* 向此对象主节点注册指定的节点,使其被应用到页面中
49+
* @param {HTMLElement} NodeObj 节点对象
50+
* @return {void}
51+
*/
52+
this.RegisteredNode = function (NodeObj) {
53+
var NodeObject = this.MainNodeObject.appendChild(NodeObj);
54+
this.Node_Data_List.push(NodeObject);
55+
}
56+
57+
/**
58+
* 获取当前控制节点子节点长度
59+
*/
60+
this.length = function () {
61+
return this.Node_Data_List.length;
62+
}
63+
64+
/**
65+
* 清空所有子节点
66+
*/
67+
this.remove = function () {
68+
this.MainNodeObject.remove();
69+
}
70+
71+
/**
72+
* 用于索引自动管理的控件
73+
* @param {int} Key 要删除的键
74+
* @return {HTMLElement} 被删除的节点控件
75+
*/
76+
this.removeChild = function (Key) {
77+
// 判断是数字还是字符串
78+
switch (typeof Key) {
79+
case 'number':
80+
var Del_Node = this.MainNodeObject.removeChild(this.Node_Data_List[Key]);
81+
this.Node_Data_List.splice(Key, 1);
82+
return Del_Node;
83+
case 'string':
84+
for (var index = 0; index < this.length(); index++) {
85+
var Node = this.indexOf(index);
86+
if (Node.id == Key) {
87+
var Del_Node = this.MainNodeObject.removeChild(this.Node_Data_List[index]);
88+
this.Node_Data_List.splice(index, 1);
89+
return Del_Node;
90+
}
91+
}
92+
return undefined
93+
94+
default:
95+
return undefined;
96+
}
97+
}
98+
99+
/**
100+
* 用于索引自动管理的控件
101+
* @param {int} Key 要索引的键
102+
* @return {HTMLElement} 被索引的节点控件
103+
*/
104+
this.indexOf = function (Key) {
105+
// 判断是数字还是字符串
106+
switch (typeof Key) {
107+
case 'number':
108+
return this.Node_Data_List[Key];
109+
case 'string':
110+
for (var index = 0; index < this.length(); index++) {
111+
var Node = this.Node_Data_List[index];
112+
if (Node.id == Key) {
113+
return Node;
114+
}
115+
}
116+
return undefined
117+
118+
default:
119+
return undefined;
120+
}
121+
}
122+
123+
// 初始化
124+
this.constructor(MainNodeID);
125+
}
126+
127+
/**
128+
* 新增指定类型的节点对象,在注册后将会被应用到页面中
129+
* @param {JSON} NodeDescription 节点描述,以下为特殊的属性(区分大小写)
130+
* [Tag: 标签,Text: 文本内容,Child: 子节点的描述,Checked: 如果是按钮,是否处于选中状态]
131+
* 其他都会被设置到属性上
132+
* @return {HTMLElement} 节点控制对象
133+
*/
134+
ControlNode.NewNode = function (NodeDescription) {
135+
// 创建当前节点描述
136+
var node = ControlNode.getNode(NodeDescription.Tag);
137+
138+
// 遍历属性,将其添加到属性中
139+
Object.keys(NodeDescription).forEach(Attributes_Name => {
140+
// 除非这个属性名在这个列表中
141+
switch (Attributes_Name) {
142+
case "Tag":
143+
case "Child":
144+
// 这部分是要跳过的属性类型,此部分的内容将在其他位置处理
145+
break;
146+
case "Text":
147+
// 处理文本(简称)
148+
node.innerText = NodeDescription[Attributes_Name];
149+
break;
150+
case "Checked":
151+
// 处理选项信息,在这里额外处理
152+
node.checked = NodeDescription[Attributes_Name];
153+
break;
154+
155+
default:
156+
var AttributesObject = document.createAttribute(Attributes_Name);
157+
AttributesObject.value = NodeDescription[Attributes_Name];
158+
node.setAttributeNode(AttributesObject);
159+
break;
160+
}
161+
});
162+
163+
// 检查是否有下级节点
164+
if (NodeDescription.Child != undefined) {
165+
// 如果有,就遍历此节点并添加至自身
166+
NodeDescription.Child.forEach(Child => {
167+
var Child_node = ControlNode.NewNode(Child);
168+
// 将子节点添加至自身
169+
node.appendChild(Child_node);
170+
});
171+
}
172+
173+
return node;
174+
}
175+
176+
/**
177+
* 获取一个新的节点对象
178+
* @param {string} NodeType 节点类型
179+
* @return {HTMLElement} 指定的节点类型对象
180+
*/
181+
ControlNode.getNode = function (NodeType) {
182+
return document.createElement(NodeType);
183+
}
184+
185+
/**
186+
* 获取一个指定样式的输入框
187+
* @param {String} NodeDataType 节点数据类型,以下是支持的值
188+
* [boolean/switch,Integer,Range,String]
189+
* 当此参数为Range时,必须提供Candidate参数
190+
* @param {*} Value 默认值
191+
* @param {Array} Candidate 待选列表
192+
* @param {boolean} isDisable 是否禁用此输入框的操作(暂未开放)
193+
* @return {JSON} 此输入控件的描述JSON对象
194+
*/
195+
ControlNode.getInputNode = function (NodeDataType, Value, Candidate, isDisable) {
196+
switch (NodeDataType) {
197+
case 'boolean':
198+
case 'switch':
199+
return JSON.parse(JSON.stringify({
200+
"Tag": "input",
201+
"type": "checkbox",
202+
"Class": "switch",
203+
"Checked": Value,
204+
"InputType": "Switch"
205+
}));
206+
case 'Integer':
207+
return JSON.parse(JSON.stringify({
208+
"Tag": "input",
209+
"type": "number",
210+
"placeholder": parseInt(Value),
211+
"value": parseInt(Value),
212+
"InputType": "Integer"
213+
}));
214+
case 'Range':
215+
return JSON.parse(JSON.stringify({
216+
"Tag": "div",
217+
"InputType": "Range",
218+
"Child": [
219+
{
220+
"Tag": "span",
221+
"Text": Value
222+
},
223+
{
224+
"Tag": "input",
225+
"type": "range",
226+
"onchange": "",
227+
"value": parseInt(Value),
228+
"min": parseInt(Candidate[0].Value.split('..')[0]),
229+
"max": parseInt(Candidate[0].Value.split('..')[1])
230+
}
231+
]
232+
}));
233+
234+
235+
case 'String':
236+
return JSON.parse(JSON.stringify({
237+
"Tag": "input",
238+
"placeholder": Value,
239+
"value": Value,
240+
"InputType": "String",
241+
}));
242+
243+
default:
244+
return JSON.parse(JSON.stringify({
245+
"Tag": "input"
246+
}));
247+
}
248+
}
249+
250+
/**
251+
* 获取一个指定样式的输入框
252+
* @param {String} NodeDataType 节点数据类型,以下是支持的值
253+
* [default: 默认形式, link: 链接形式]
254+
* @param {String} Value 按钮的显示内容
255+
* @param {function,String} onClick 点击后产生的效果,随着NodeDataType改变
256+
* [default: {function} 一个回调函数,link: {String} 一个链接地址]
257+
* @param {boolean} isDisable 是否禁用此按钮的操作
258+
* @return {JSON} 此输入控件的描述JSON对象
259+
*/
260+
ControlNode.getButtonNode = function (NodeDataType, Value, onClick, isDisable) {
261+
switch (NodeDataType) {
262+
case 'link':
263+
return JSON.parse(JSON.stringify({
264+
"Tag": "a",
265+
"Class": isDisable ? "button disable" : "button enable",
266+
"Href": onClick,
267+
"Text": Value
268+
}));
269+
270+
default:
271+
return JSON.parse(JSON.stringify({
272+
"Tag": "button",
273+
"Disabled": isDisable ? "disable" : "",
274+
"OnClick": onClick,
275+
"Text": Value
276+
}));
277+
}
278+
}
279+
280+
/**
281+
* 索引
282+
* @param {int,String} Key 要用于索引的Key
283+
* @return {ControlNode} 指定的控制对象
284+
*/
285+
ControlNode.indexOf = function (Key) {
286+
// 判断是数字还是字符串
287+
switch (typeof Key) {
288+
case 'number':
289+
return ControlNode.ObjectList[Key];
290+
case 'string':
291+
for (var index = 0; index < ControlNode.ObjectList.length; index++) {
292+
var controlNode = ControlNode.ObjectList[index];
293+
if (controlNode.Name == Key) {
294+
return controlNode;
295+
}
296+
}
297+
return undefined
298+
299+
default:
300+
return undefined;
301+
}
302+
}
303+
304+
/**
305+
* 获取指定节点的控制对象
306+
* @param {string} MainNodeID 指定要作为主节点的ID
307+
* @return {ControlNode} 指定的控制对象
308+
*/
309+
ControlNode.valueOf = function (MainNodeID) {
310+
// 检查是否存在重复的对象,如果有,就直接返回,没有的情况下才创建新对象
311+
if (ControlNode.indexOf(MainNodeID) == undefined) {
312+
// 如果没有,就New新的值
313+
return new ControlNode(MainNodeID);
314+
} else {
315+
// 如果不为空,就返回指定的内容
316+
return ControlNode.indexOf(MainNodeID);
317+
}
318+
}
319+
320+
/**
321+
* 将指定ID的控制节点转为一个JSON格式的节点描述
322+
* @param {String,Object} NodeID
323+
* @return {JSON_Object} JSON字符串
324+
*/
325+
ControlNode.HTMLElement2JSON_NodeDescription = function (NodeID) {
326+
// 创建描述
327+
var NodeDescription = Object();
328+
// 取得对象
329+
switch (typeof NodeID) {
330+
case 'string':
331+
var NodeObj = document.getElementById(NodeID);
332+
break;
333+
case 'object':
334+
var NodeObj = NodeID;
335+
break;
336+
default:
337+
var NodeObj = NodeID;
338+
break;
339+
}
340+
// 解析当前节点配置
341+
for (var Node_index = 0; Node_index < NodeObj.attributes.length; Node_index++) {
342+
var attributeName = NodeObj.attributes[Node_index].name;
343+
NodeDescription[attributeName] = NodeObj.getAttribute(attributeName);
344+
}
345+
// 解析特殊内容
346+
NodeDescription['Tag'] = NodeObj.tagName;
347+
// 检查是否有子节点
348+
if (NodeObj.childNodes.length > 0) {
349+
for (var Child_index = 0; Child_index < NodeObj.childNodes.length; Child_index++) {
350+
var Child = NodeObj.childNodes[Child_index];
351+
// 如果无法查到子节点的标签,就说明是文本类型,存入Text中
352+
if (Child.tagName == undefined) {
353+
NodeDescription["Text"] = Child.data;
354+
} else {
355+
if (NodeDescription.Child == undefined)
356+
NodeDescription.Child = [];
357+
NodeDescription.Child.push(ControlNode.HTMLElement2JSON_NodeDescription(Child));
358+
}
359+
}
360+
}
361+
return NodeDescription;
362+
}
363+
364+
/**
365+
* ControlNodeObject自动维护的输入框对象表,用于追踪操作对象
366+
*/
367+
ControlNode.ObjectList = [];

0 commit comments

Comments
 (0)