@joyzl/eno 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +124 -0
- package/index.js +707 -0
- package/package.json +28 -0
package/README.md
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# eno
|
2
|
+
提供HTML标签与数据对象之间的互操作支持。
|
3
|
+
|
4
|
+
## 安装
|
5
|
+
``` cmd
|
6
|
+
npm install @joyzl/eno
|
7
|
+
```
|
8
|
+
|
9
|
+
``` javascript
|
10
|
+
import eno from `eno`;
|
11
|
+
```
|
12
|
+
|
13
|
+
## 使用
|
14
|
+
|
15
|
+
### sets
|
16
|
+
将数据对象(例如从服务器获取的JSON对象)设置到HTML元素以显示数据。
|
17
|
+
|
18
|
+
首先建立HTML标签元素如下所示:
|
19
|
+
```html
|
20
|
+
<div id="user">
|
21
|
+
<span name="realname"></span>
|
22
|
+
<span name="birthday"></span>
|
23
|
+
</div>
|
24
|
+
```
|
25
|
+
|
26
|
+
将数据对象设置到HTML标签元素。
|
27
|
+
```javascript
|
28
|
+
let user = {
|
29
|
+
realname: "小明",
|
30
|
+
birthday: "1992-5-27"
|
31
|
+
};
|
32
|
+
let div = document.getElementById("user");
|
33
|
+
eno.sets(div, user);
|
34
|
+
```
|
35
|
+
|
36
|
+
数据对象的字段值将根据HTML标签元素指定的name属性插入到标签中。
|
37
|
+
```html
|
38
|
+
<div id="user">
|
39
|
+
<span name="realname">小明</span>
|
40
|
+
<span name="birthday">1992-5-27</span>
|
41
|
+
</div>
|
42
|
+
```
|
43
|
+
|
44
|
+
### gets
|
45
|
+
从HTML元素获取JSON对象以获得用户数据。
|
46
|
+
与sets方法的功能正好相反。
|
47
|
+
|
48
|
+
假设有以下HTML实例:
|
49
|
+
```html
|
50
|
+
<div id="user">
|
51
|
+
<span name="realname">小明</span>
|
52
|
+
<span name="birthday">1992-5-27</span>
|
53
|
+
</div>
|
54
|
+
```
|
55
|
+
|
56
|
+
执行gets方法获取数据对象:
|
57
|
+
```javascript
|
58
|
+
let values = eno.gets(element);
|
59
|
+
//{
|
60
|
+
// realname: "小明",
|
61
|
+
// birthday: "1992-5-27"
|
62
|
+
//}
|
63
|
+
```
|
64
|
+
|
65
|
+
获取表单输入值,gets将识别传入参数是否表单。
|
66
|
+
```html
|
67
|
+
<form>
|
68
|
+
<input type="text" name="user" value="小张"/>
|
69
|
+
<input type="text" name="birthday" value="1982-10-30"/>
|
70
|
+
</form>
|
71
|
+
```
|
72
|
+
|
73
|
+
执行gets方法获取form数据对象:
|
74
|
+
```javascript
|
75
|
+
let values = eno.gets(element);
|
76
|
+
//{
|
77
|
+
// realname: "小张",
|
78
|
+
// birthday: "1982-10-30"
|
79
|
+
//}
|
80
|
+
```
|
81
|
+
|
82
|
+
|
83
|
+
### query
|
84
|
+
获取指定URL或当前URL中的查询字符串参数。
|
85
|
+
|
86
|
+
```javascript
|
87
|
+
// 从当前URL获取参数
|
88
|
+
let token = eno.query("token");
|
89
|
+
|
90
|
+
// 从指定URL获取参数
|
91
|
+
let url = "http://www.joyzl.net/test?name=value";
|
92
|
+
let value = eno.query(url, "name");
|
93
|
+
```
|
94
|
+
|
95
|
+
### select
|
96
|
+
获取符合指定选择器字符串的第一个元素。
|
97
|
+
|
98
|
+
在整个文档实例范围中查找:
|
99
|
+
```javascript
|
100
|
+
let element = eno.select("#user");
|
101
|
+
```
|
102
|
+
|
103
|
+
在指定元素实例范围中查找:
|
104
|
+
```javascript
|
105
|
+
let form = eno.select("form");
|
106
|
+
let user = eno.select(form, "#user");
|
107
|
+
```
|
108
|
+
|
109
|
+
|
110
|
+
### selects
|
111
|
+
获取符合指定选择器字符串的所有元素。
|
112
|
+
|
113
|
+
|
114
|
+
在整个文档实例范围中查找:
|
115
|
+
```javascript
|
116
|
+
let elements = eno.selects("#user");
|
117
|
+
```
|
118
|
+
|
119
|
+
|
120
|
+
在指定元素实例范围中查找:
|
121
|
+
```javascript
|
122
|
+
let forms = eno.selects("form");
|
123
|
+
let users = eno.selects(form, "#user");
|
124
|
+
```
|
package/index.js
ADDED
@@ -0,0 +1,707 @@
|
|
1
|
+
// HTML5 Node Element
|
2
|
+
// Easy Node Object
|
3
|
+
// 提供HTML标签与数据对象之间的互操作支持。
|
4
|
+
|
5
|
+
export default {
|
6
|
+
create,
|
7
|
+
remove,
|
8
|
+
|
9
|
+
select,
|
10
|
+
selects,
|
11
|
+
query,
|
12
|
+
on,
|
13
|
+
|
14
|
+
toggle,
|
15
|
+
show,
|
16
|
+
hide,
|
17
|
+
|
18
|
+
gets,
|
19
|
+
sets,
|
20
|
+
entity,
|
21
|
+
action
|
22
|
+
}
|
23
|
+
|
24
|
+
/**
|
25
|
+
* 显示单个/多个元素
|
26
|
+
* @param {Element} element
|
27
|
+
*/
|
28
|
+
function show(element) {
|
29
|
+
if (element) {
|
30
|
+
if (element.trim) {
|
31
|
+
show(selects(element));
|
32
|
+
} else
|
33
|
+
if (element.length) {
|
34
|
+
for (let i = 0; i < element.length; i++) {
|
35
|
+
show(element[i]);
|
36
|
+
}
|
37
|
+
} else
|
38
|
+
if (element.nodeType) {
|
39
|
+
element.hidden = false;
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
/**
|
44
|
+
* 隐藏单个/多个元素
|
45
|
+
* @param {Element} element
|
46
|
+
*/
|
47
|
+
function hide(element) {
|
48
|
+
if (element) {
|
49
|
+
if (element.trim) {
|
50
|
+
hide(selects(element));
|
51
|
+
} else
|
52
|
+
if (element.length) {
|
53
|
+
for (let i = 0; i < element.length; i++) {
|
54
|
+
hide(element[i]);
|
55
|
+
}
|
56
|
+
} else
|
57
|
+
if (element.nodeType) {
|
58
|
+
element.hidden = true;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
/**
|
63
|
+
* 切换指定元素显示,其余元素隐藏
|
64
|
+
* @param {Object} parent 父级
|
65
|
+
* @param {Object} element 要显示的元素
|
66
|
+
*/
|
67
|
+
function toggle(parent, element) {
|
68
|
+
if (arguments.length == 1) {
|
69
|
+
// toggle(element);
|
70
|
+
|
71
|
+
}
|
72
|
+
if (parent && element) {
|
73
|
+
if (parent.trim) {
|
74
|
+
parent = select(parent);
|
75
|
+
}
|
76
|
+
if (element.trim) {
|
77
|
+
element = select(element);
|
78
|
+
}
|
79
|
+
if (element.parentElement != parent) {
|
80
|
+
parent.appendChild(element);
|
81
|
+
}
|
82
|
+
for (let i = 0; i < parent.children.length; i++) {
|
83
|
+
if (element == parent.children[i]) {
|
84
|
+
parent.children[i].hidden = false;
|
85
|
+
} else {
|
86
|
+
parent.children[i].hidden = true;
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
/**
|
93
|
+
* 在指定元素内/整个文档查找标签
|
94
|
+
* @param {Element} element 元素内
|
95
|
+
* @param {String} selector 选择器
|
96
|
+
*/
|
97
|
+
function select(element, selector) {
|
98
|
+
// 仅指定1个参数
|
99
|
+
if (arguments.length == 1) {
|
100
|
+
// select(selector);
|
101
|
+
selector = element;
|
102
|
+
return document.querySelector(selector);
|
103
|
+
}
|
104
|
+
// 指定了2个参数
|
105
|
+
if (arguments.length >= 2) {
|
106
|
+
// select(element, selector);
|
107
|
+
if (element) {
|
108
|
+
if (element.trim) {
|
109
|
+
element = document.querySelectorAll(element);
|
110
|
+
}
|
111
|
+
if (element.nodeType) {
|
112
|
+
return element.querySelector(selector);
|
113
|
+
} else
|
114
|
+
if (Array.isArray(element)) {
|
115
|
+
let node;
|
116
|
+
for (let i = 0; i < elements.length; i++) {
|
117
|
+
node = elements[i].querySelector(selector);
|
118
|
+
if (node) {
|
119
|
+
return node;
|
120
|
+
}
|
121
|
+
}
|
122
|
+
}
|
123
|
+
return null;
|
124
|
+
} else {
|
125
|
+
return document.querySelector(selector);
|
126
|
+
}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
|
130
|
+
/**
|
131
|
+
* 在指定元素内/整个文档查找标签
|
132
|
+
* @param {Element} element 元素内
|
133
|
+
* @param {String} selector 选择器
|
134
|
+
* @returns {NodeList} 元素集合/空集合
|
135
|
+
*/
|
136
|
+
function selects(element, selector) {
|
137
|
+
// 仅指定1个参数
|
138
|
+
if (arguments.length == 1) {
|
139
|
+
// select(selector);
|
140
|
+
selector = element;
|
141
|
+
return document.querySelectorAll(selector);
|
142
|
+
}
|
143
|
+
// 指定了2个参数
|
144
|
+
if (arguments.length >= 2) {
|
145
|
+
// select(element, selector);
|
146
|
+
let nodes, items = new Array();
|
147
|
+
if (element.trim) {
|
148
|
+
element = document.querySelectorAll(element);
|
149
|
+
}
|
150
|
+
if (Array.isArray(element)) {
|
151
|
+
for (let i = 0; i < element.length; i++) {
|
152
|
+
nodes = element[i].querySelectorAll(selector);
|
153
|
+
if (nodes && nodes.length) {
|
154
|
+
for (let i = 0; i < nodes.length; ++i) {
|
155
|
+
items.push(nodes[i]);
|
156
|
+
}
|
157
|
+
}
|
158
|
+
}
|
159
|
+
} else {
|
160
|
+
nodes = element.querySelectorAll(selector);
|
161
|
+
if (nodes && nodes.length) {
|
162
|
+
for (let i = 0; i < nodes.length; ++i) {
|
163
|
+
items.push(nodes[i]);
|
164
|
+
}
|
165
|
+
}
|
166
|
+
}
|
167
|
+
return items;
|
168
|
+
}
|
169
|
+
}
|
170
|
+
|
171
|
+
/**
|
172
|
+
* 绑定事件
|
173
|
+
* @param {Element} element
|
174
|
+
* @param {String} selector
|
175
|
+
* @param {String} evt
|
176
|
+
* @param {Function} listener
|
177
|
+
*/
|
178
|
+
function on(element, selector, evt, listener) {
|
179
|
+
if (arguments.length == 3) {
|
180
|
+
// on(element/selector, evt, listener);
|
181
|
+
listener = evt;
|
182
|
+
evt = selector;
|
183
|
+
if (element.trim) {
|
184
|
+
element = selects(element);
|
185
|
+
}
|
186
|
+
} else
|
187
|
+
if (arguments.length == 4) {
|
188
|
+
// on(element, selector, evt, listener);
|
189
|
+
element = selects(element, selector);
|
190
|
+
} else {
|
191
|
+
return;
|
192
|
+
}
|
193
|
+
|
194
|
+
if (Array.isArray(element)) {
|
195
|
+
for (let i = 0; i < element.length; i++) {
|
196
|
+
element[i].addEventListener(evt, listener);
|
197
|
+
}
|
198
|
+
} else {
|
199
|
+
element.addEventListener(evt, listener);
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
// 这个临时标签用于解析HTML字符串
|
204
|
+
const TEMP = document.createElement("div");
|
205
|
+
|
206
|
+
/**
|
207
|
+
* 字符串创建HTML元素;
|
208
|
+
* A仅创建;
|
209
|
+
* B创建并添加到末尾:append;
|
210
|
+
* C创建并替换已有元素:replace;
|
211
|
+
* @param {String} parent
|
212
|
+
* @param {String} html 字符串形式的HTML内容
|
213
|
+
* @param {String} place append/replace
|
214
|
+
* @return {Element} 单个/多个元素
|
215
|
+
*/
|
216
|
+
function create(parent, html, place) {
|
217
|
+
if (arguments.length == 0) {
|
218
|
+
// create();
|
219
|
+
return null;
|
220
|
+
} else
|
221
|
+
if (arguments.length == 1) {
|
222
|
+
// create(html);
|
223
|
+
html = parent;
|
224
|
+
parent = null;
|
225
|
+
} else
|
226
|
+
if (arguments.length == 2) {
|
227
|
+
// create(parent,html);
|
228
|
+
place = 'append';
|
229
|
+
if (parent) {
|
230
|
+
if (parent.nodeType) {} else {
|
231
|
+
parent = select(parent);
|
232
|
+
}
|
233
|
+
} else {
|
234
|
+
parent = document.body;
|
235
|
+
}
|
236
|
+
} else
|
237
|
+
if (arguments.length == 3) {
|
238
|
+
// create(parent,html,place);
|
239
|
+
if (parent) {
|
240
|
+
if (parent.nodeType) {} else {
|
241
|
+
parent = select(parent);
|
242
|
+
}
|
243
|
+
} else {
|
244
|
+
parent = document.body;
|
245
|
+
}
|
246
|
+
}
|
247
|
+
|
248
|
+
// 创建元素
|
249
|
+
TEMP.innerHTML = html;
|
250
|
+
let element;
|
251
|
+
if (TEMP.childElementCount == 1) {
|
252
|
+
element = TEMP.children[0];
|
253
|
+
element.remove();
|
254
|
+
} else
|
255
|
+
if (TEMP.childElementCount > 1) {
|
256
|
+
element = new Array();
|
257
|
+
for (let i = 0; i < TEMP.childElementCount; ++i) {
|
258
|
+
element.push(TEMP.children[i]);
|
259
|
+
TEMP.children[i].remove();
|
260
|
+
}
|
261
|
+
} else {
|
262
|
+
return null;
|
263
|
+
}
|
264
|
+
|
265
|
+
// 添加元素到文档
|
266
|
+
if (parent) {
|
267
|
+
if ("append" === place) {
|
268
|
+
if (element.length) {
|
269
|
+
for (let i = 0; i < element.length; i++) {
|
270
|
+
parent.appendChild(element[i]);
|
271
|
+
}
|
272
|
+
} else {
|
273
|
+
parent.appendChild(element);
|
274
|
+
}
|
275
|
+
} else
|
276
|
+
if ("replace" === place) {
|
277
|
+
if (parent.parentElement) {
|
278
|
+
if (element.length) {
|
279
|
+
// 待验证
|
280
|
+
parent.parentElement.replaceWith(element);
|
281
|
+
} else {
|
282
|
+
parent.parentElement.replaceChild(parent, element);
|
283
|
+
}
|
284
|
+
}
|
285
|
+
} else {
|
286
|
+
console.error("eno.create 不明确的参数" + place);
|
287
|
+
}
|
288
|
+
}
|
289
|
+
return element;
|
290
|
+
}
|
291
|
+
|
292
|
+
/**
|
293
|
+
* 从文档移除一个或多个元素
|
294
|
+
* @param {Element} element 元素/元素数组
|
295
|
+
*/
|
296
|
+
function remove(element) {
|
297
|
+
if (element) {
|
298
|
+
if (element.trim) {
|
299
|
+
// remove("p");
|
300
|
+
element = selects(element);
|
301
|
+
}
|
302
|
+
if (element.tagName) {
|
303
|
+
// remove(document.getElementById("test"));
|
304
|
+
element.remove();
|
305
|
+
} else
|
306
|
+
if (element.length) {
|
307
|
+
// remove(["p","span"]);
|
308
|
+
// remove(document.getElementByTagName("div"));
|
309
|
+
for (let i = 0; i < element.length; i++) {
|
310
|
+
remove(element[i]);
|
311
|
+
}
|
312
|
+
}
|
313
|
+
}
|
314
|
+
}
|
315
|
+
|
316
|
+
/**
|
317
|
+
* 读取 URL 中的 Query String 参数值
|
318
|
+
* @param {String} name 参数名
|
319
|
+
*/
|
320
|
+
function query(url, name) {
|
321
|
+
if (arguments.length == 1) {
|
322
|
+
// getQueryString(name)
|
323
|
+
name = url;
|
324
|
+
// window.location.search 返回从问号?开始的URL查询部分
|
325
|
+
// ?name1=value1&name2=value2
|
326
|
+
url = window.location.search;
|
327
|
+
}
|
328
|
+
if (arguments.length == 2) {
|
329
|
+
// getQueryString(url, name)
|
330
|
+
let index = url.indexof("?");
|
331
|
+
if (index > 0) {
|
332
|
+
url = url.substring(index);
|
333
|
+
} else {
|
334
|
+
return null;
|
335
|
+
}
|
336
|
+
}
|
337
|
+
|
338
|
+
if (url) {
|
339
|
+
let start = url.indexOf(name);
|
340
|
+
if (start >= 0) {
|
341
|
+
start += name.length;
|
342
|
+
if (url.charAt(start) == '=') {
|
343
|
+
start++;
|
344
|
+
let end = url.indexOf('&', start);
|
345
|
+
if (end >= 0) {
|
346
|
+
return url.substring(start, end);
|
347
|
+
}
|
348
|
+
return url.substring(start);
|
349
|
+
}
|
350
|
+
}
|
351
|
+
}
|
352
|
+
return null;
|
353
|
+
}
|
354
|
+
|
355
|
+
// 默认转换函数
|
356
|
+
function defaultConverter(element, parameter, name) {}
|
357
|
+
|
358
|
+
/**
|
359
|
+
* 从指定元素获取值以JSON对象返回{name:value}
|
360
|
+
* @param {Element} element 元素
|
361
|
+
* @param {Function} converter 转换
|
362
|
+
* @returns {Object} {name1:value1,name2:value2,...}
|
363
|
+
*/
|
364
|
+
function gets(element, converter = defaultConverter) {
|
365
|
+
if (element) {
|
366
|
+
if (element.trim) {
|
367
|
+
element = selects(element);
|
368
|
+
}
|
369
|
+
if (Array.isArray(element)) {
|
370
|
+
let parameter = {},
|
371
|
+
parameters = new Array();
|
372
|
+
for (let i = 0; i < element.length; i++) {
|
373
|
+
get(element[i], parameter, converter);
|
374
|
+
if (Object.keys(parameter).length) {
|
375
|
+
parameters.push(parameter);
|
376
|
+
parameter = {};
|
377
|
+
}
|
378
|
+
}
|
379
|
+
return parameters;
|
380
|
+
} else {
|
381
|
+
let parameter = {};
|
382
|
+
get(element, parameter, converter);
|
383
|
+
return parameter;
|
384
|
+
}
|
385
|
+
}
|
386
|
+
}
|
387
|
+
/**
|
388
|
+
* 从指定JSON设置元素值,以name属性作为标识
|
389
|
+
* @param {Element} element 元素
|
390
|
+
* @param {Object} parameter 对象
|
391
|
+
* @param {Function} converter 转换
|
392
|
+
* @returns {Element} element
|
393
|
+
*/
|
394
|
+
function sets(element, parameter, converter = defaultConverter) {
|
395
|
+
if (element) {
|
396
|
+
if (element.trim) {
|
397
|
+
// 元素选择字符串
|
398
|
+
element = selects(element);
|
399
|
+
if (element.length == 0) {
|
400
|
+
return null;
|
401
|
+
} else
|
402
|
+
if (element.length == 1) {
|
403
|
+
element = element[0];
|
404
|
+
} else {
|
405
|
+
// 多个匹配元素
|
406
|
+
}
|
407
|
+
}
|
408
|
+
|
409
|
+
if (parameter) {
|
410
|
+
if (Array.isArray(parameter)) {
|
411
|
+
// if (element.nodeType) {
|
412
|
+
// if (element.childElementCount) {
|
413
|
+
// element = element.children;
|
414
|
+
// } else {
|
415
|
+
// // ???
|
416
|
+
// return null;
|
417
|
+
// }
|
418
|
+
// }
|
419
|
+
|
420
|
+
let i = 0;
|
421
|
+
if (element.ENO_SETS) {
|
422
|
+
element.ENO_SETS = element.ENO_SETS + 1;
|
423
|
+
} else {
|
424
|
+
element.ENO_SETS = 1;
|
425
|
+
// ...<template>...
|
426
|
+
for (; i < element.children.length; i++) {
|
427
|
+
if (element.children[i].content) {
|
428
|
+
element.template = element.children[i];
|
429
|
+
element.a = ++i;
|
430
|
+
element.b = element.children.length - i;
|
431
|
+
break;
|
432
|
+
}
|
433
|
+
}
|
434
|
+
}
|
435
|
+
|
436
|
+
if (element.template) {
|
437
|
+
// 已定义模板
|
438
|
+
if (parameter.length) { // [a,b]
|
439
|
+
let node, n;
|
440
|
+
// 构造填充元素
|
441
|
+
for (i = 0; i < parameter.length; i++) {
|
442
|
+
if (element.a + i < element.children.length - element.b) {
|
443
|
+
// 重用已有元素
|
444
|
+
for (n = 0; n < element.template.content.childElementCount; n++) {
|
445
|
+
node = element.children[element.a + i + n];
|
446
|
+
node.userData = parameter[i];
|
447
|
+
set(node, parameter[i], converter);
|
448
|
+
node.hidden = false;
|
449
|
+
}
|
450
|
+
} else {
|
451
|
+
// 克隆新的元素(DocumentFragment)
|
452
|
+
node = element.template.content.cloneNode(true);
|
453
|
+
n = i * element.template.content.childElementCount;
|
454
|
+
node = element.insertBefore(node, element.children[element.a + n]);
|
455
|
+
node = node.children;
|
456
|
+
for (n = 0; n < node.length; n++) {
|
457
|
+
node[n].userData = parameter[i];
|
458
|
+
set(node[n], parameter[i], converter);
|
459
|
+
node[n].hidden = false;
|
460
|
+
}
|
461
|
+
}
|
462
|
+
}
|
463
|
+
// 移除多余元素
|
464
|
+
n = i * element.template.content.childElementCount;
|
465
|
+
i = element.a + element.b;
|
466
|
+
while (element.children.length > i + n) {
|
467
|
+
element.children[element.a + n].remove();
|
468
|
+
}
|
469
|
+
return element;
|
470
|
+
} else { // []
|
471
|
+
// 移除多余元素
|
472
|
+
i = element.a + element.b;
|
473
|
+
while (element.length > i) {
|
474
|
+
element[element.a + 1].remove();
|
475
|
+
}
|
476
|
+
return element;
|
477
|
+
}
|
478
|
+
} else {
|
479
|
+
// 未使用模板
|
480
|
+
if (parameter.length) { // [a,b]
|
481
|
+
let node;
|
482
|
+
// 构造填充元素
|
483
|
+
for (i = 0; i < parameter.length; i++) {
|
484
|
+
if (i < element.children.length) {
|
485
|
+
// 重用已有元素
|
486
|
+
node = element.children[i];
|
487
|
+
} else if (node) {
|
488
|
+
// 克隆新的元素
|
489
|
+
node = element.appendChild(node.cloneNode(true));
|
490
|
+
} else {
|
491
|
+
// 干不了
|
492
|
+
continue;
|
493
|
+
}
|
494
|
+
node.userData = parameter[i];
|
495
|
+
set(node, parameter[i], converter);
|
496
|
+
node.hidden = false;
|
497
|
+
}
|
498
|
+
// 移除多余元素
|
499
|
+
while (element.children.length > i) {
|
500
|
+
element.children[i].remove();
|
501
|
+
}
|
502
|
+
return element;
|
503
|
+
} else { // []
|
504
|
+
// 保留模板
|
505
|
+
element.children[0].hidden = true;
|
506
|
+
// 移除多余元素
|
507
|
+
while (element.children.length > 1) {
|
508
|
+
element.children[1].remove();
|
509
|
+
}
|
510
|
+
return element;
|
511
|
+
}
|
512
|
+
}
|
513
|
+
} else { // Object
|
514
|
+
if (element.nodeType) {
|
515
|
+
element.userData = parameter;
|
516
|
+
set(element, parameter, converter);
|
517
|
+
return element;
|
518
|
+
}
|
519
|
+
if (element.length) {
|
520
|
+
for (let node, i = 0; i < element.length; i++) {
|
521
|
+
node = element[i];
|
522
|
+
node.userData = parameter;
|
523
|
+
set(node, parameter, converter);
|
524
|
+
}
|
525
|
+
return element;
|
526
|
+
}
|
527
|
+
}
|
528
|
+
} else { // null / undefine
|
529
|
+
if (element.nodeType) {
|
530
|
+
element.userData = null;
|
531
|
+
set(element, null, converter);
|
532
|
+
return element;
|
533
|
+
}
|
534
|
+
if (element.length) {
|
535
|
+
// 保留模板
|
536
|
+
element[0].hidden = true;
|
537
|
+
// 移除多余元素
|
538
|
+
while (element.length > 1) {
|
539
|
+
element[1].remove();
|
540
|
+
}
|
541
|
+
return element;
|
542
|
+
}
|
543
|
+
}
|
544
|
+
}
|
545
|
+
}
|
546
|
+
/**
|
547
|
+
* 获取元素值
|
548
|
+
* <input name="AAA" value="123"/>
|
549
|
+
* <span name="AAA">123</span>
|
550
|
+
* <img name="AAA" src="123"/>
|
551
|
+
* <i case="AAA"></i>
|
552
|
+
*/
|
553
|
+
function get(element, parameter, converter) {
|
554
|
+
let name = element.getAttribute("case");
|
555
|
+
if (name && name.length) {
|
556
|
+
converter(element, parameter, name);
|
557
|
+
}
|
558
|
+
name = element.getAttribute("name");
|
559
|
+
if (name && name.length) {
|
560
|
+
if (element.form) {
|
561
|
+
valu(parameter, name, element.value);
|
562
|
+
} else
|
563
|
+
if (element.src) {
|
564
|
+
valu(parameter, name, element.src);
|
565
|
+
} else {
|
566
|
+
valu(parameter, name, element.innerText);
|
567
|
+
}
|
568
|
+
}
|
569
|
+
if (element.childElementCount) {
|
570
|
+
for (let i = 0; i < element.children.length; i++) {
|
571
|
+
get(element.children[i], parameter);
|
572
|
+
}
|
573
|
+
}
|
574
|
+
}
|
575
|
+
/**
|
576
|
+
* 设置元素值
|
577
|
+
* <input name="AAA" value="123"/>
|
578
|
+
* <span name="AAA">123</span>
|
579
|
+
* <img name="AAA" src="123"/>
|
580
|
+
* <i case="AAA"></i>
|
581
|
+
*/
|
582
|
+
function set(element, parameter, converter) {
|
583
|
+
let name = element.getAttribute("case");
|
584
|
+
if (name && name.length) {
|
585
|
+
converter(element, parameter, name);
|
586
|
+
}
|
587
|
+
name = element.getAttribute("name");
|
588
|
+
if (name && name.length) {
|
589
|
+
if (element.form) {
|
590
|
+
element.value = text(vale(parameter, name));
|
591
|
+
} else
|
592
|
+
if (element.src) {
|
593
|
+
element.src = text(vale(parameter, name));
|
594
|
+
} else {
|
595
|
+
element.innerText = text(vale(parameter, name));
|
596
|
+
}
|
597
|
+
}
|
598
|
+
if (element.childElementCount) {
|
599
|
+
for (let i = 0; i < element.children.length; i++) {
|
600
|
+
set(element.children[i], parameter, converter);
|
601
|
+
}
|
602
|
+
}
|
603
|
+
}
|
604
|
+
/**
|
605
|
+
* 根据名称获取对象值
|
606
|
+
* @param {Object} o 对象
|
607
|
+
* @param {Object} name 名称 "Device.Type.Text"
|
608
|
+
* @returns {Object} value 值
|
609
|
+
*/
|
610
|
+
function vale(o, name) {
|
611
|
+
name = name.split(".");
|
612
|
+
for (let i = 0; i < name.length; i++) {
|
613
|
+
if (o) {
|
614
|
+
if (Array.isArray(o)) {
|
615
|
+
const items = new Array();
|
616
|
+
for (let a = 0; a < o.length; a++) {
|
617
|
+
if (o[a]) {
|
618
|
+
items.push(o[a][name[i]]);
|
619
|
+
}
|
620
|
+
}
|
621
|
+
o = items;
|
622
|
+
} else {
|
623
|
+
o = o[name[i]];
|
624
|
+
}
|
625
|
+
} else {
|
626
|
+
break;
|
627
|
+
}
|
628
|
+
}
|
629
|
+
return o;
|
630
|
+
}
|
631
|
+
/**
|
632
|
+
* 根据名称设置对象值
|
633
|
+
* @param {Object} o
|
634
|
+
* @param {Object} name "Device.Type.Text"
|
635
|
+
* @param {Object} value
|
636
|
+
*/
|
637
|
+
function valu(o, name, value) {
|
638
|
+
name = name.split(".");
|
639
|
+
let i = 0;
|
640
|
+
for (; i < name.length - 1; i++) {
|
641
|
+
if (o) {
|
642
|
+
if (o[name[i]]) {
|
643
|
+
o = o[name[i]];
|
644
|
+
} else {
|
645
|
+
o = o[name[i]] = {};
|
646
|
+
}
|
647
|
+
}
|
648
|
+
}
|
649
|
+
o[name[i]] = value;
|
650
|
+
return o;
|
651
|
+
}
|
652
|
+
/**
|
653
|
+
* 转换为字符串值
|
654
|
+
* @param {Object} o
|
655
|
+
*/
|
656
|
+
function text(o) {
|
657
|
+
if (Array.isArray(o)) {
|
658
|
+
// 数组值合并(逗号分割)
|
659
|
+
return o.join(',');
|
660
|
+
}
|
661
|
+
if (o != undefined) {
|
662
|
+
return o.toString();
|
663
|
+
}
|
664
|
+
return "";
|
665
|
+
}
|
666
|
+
/**
|
667
|
+
* 根据事件或元素获取由sets关联的实体对象
|
668
|
+
*/
|
669
|
+
function entity(e) {
|
670
|
+
if (e.target) {
|
671
|
+
e = e.target;
|
672
|
+
} else
|
673
|
+
if (e.srcElement) {
|
674
|
+
e = e.srcElement;
|
675
|
+
}
|
676
|
+
|
677
|
+
while (e) {
|
678
|
+
if (e.userData) {
|
679
|
+
return e.userData;
|
680
|
+
} else {
|
681
|
+
e = e.parentElement;
|
682
|
+
}
|
683
|
+
}
|
684
|
+
return null;
|
685
|
+
}
|
686
|
+
/**
|
687
|
+
* 根据事件或元素获取属性指定的动作
|
688
|
+
* @param {Event} e
|
689
|
+
* @param {String} a
|
690
|
+
*/
|
691
|
+
function action(e, a) {
|
692
|
+
if (e.target) {
|
693
|
+
e = e.target;
|
694
|
+
} else
|
695
|
+
if (e.srcElement) {
|
696
|
+
e = e.srcElement;
|
697
|
+
}
|
698
|
+
|
699
|
+
while (e) {
|
700
|
+
if (e.hasAttribute(a)) {
|
701
|
+
return true;
|
702
|
+
} else {
|
703
|
+
e = e.parentElement;
|
704
|
+
}
|
705
|
+
}
|
706
|
+
return false;
|
707
|
+
}
|
package/package.json
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
{
|
2
|
+
"name": "@joyzl/eno",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "Easy Node Object",
|
5
|
+
"main": "index.js",
|
6
|
+
"scripts": {
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
8
|
+
},
|
9
|
+
"repository": {
|
10
|
+
"type": "git",
|
11
|
+
"url": "git+https://github.com/JoyLinks/eno.git"
|
12
|
+
},
|
13
|
+
"keywords": [
|
14
|
+
"eno",
|
15
|
+
"webpack",
|
16
|
+
"html",
|
17
|
+
"json"
|
18
|
+
],
|
19
|
+
"author": "ZhangXi",
|
20
|
+
"license": "Apache-2.0",
|
21
|
+
"bugs": {
|
22
|
+
"url": "https://github.com/JoyLinks/eno/issues"
|
23
|
+
},
|
24
|
+
"homepage": "https://github.com/JoyLinks/eno#readme",
|
25
|
+
"devDependencies": {
|
26
|
+
"webpack": "^5.91.0"
|
27
|
+
}
|
28
|
+
}
|