@joyzl/eno 1.1.6 → 1.2.1
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 +4 -542
- package/dist/joyzl-eno.js +1 -0
- package/index.js +639 -514
- package/package.json +8 -4
- package/webpack.config.js +14 -0
package/index.js
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
// HTML5 Node Element
|
2
|
-
// Easy Node Object
|
3
1
|
// 提供HTML标签元素处理与数据对象之间的互操作支持。
|
2
|
+
// 用于简化 HTMLElement 与 JS JSON/Object 之间的互操作。
|
4
3
|
|
5
4
|
export default {
|
6
5
|
create,
|
@@ -14,74 +13,95 @@ export default {
|
|
14
13
|
hide,
|
15
14
|
toggle,
|
16
15
|
|
16
|
+
get,
|
17
17
|
gets,
|
18
|
+
set,
|
18
19
|
sets,
|
19
20
|
|
20
21
|
bind,
|
21
22
|
entity,
|
22
|
-
action,
|
23
23
|
element,
|
24
24
|
|
25
25
|
query
|
26
26
|
}
|
27
27
|
|
28
28
|
// 这个临时标签用于解析HTML字符串
|
29
|
-
const
|
29
|
+
const TEMPLATE = document.createElement("template");
|
30
30
|
|
31
31
|
/**
|
32
32
|
* HTML字符串创建标签元素实例
|
33
|
-
* @
|
34
|
-
* @
|
33
|
+
* @example eno.create(html);
|
34
|
+
* @param {String|HTMLElement} html 要创建为标签元素实例的HTML字符串
|
35
|
+
* @return {HTMLElement|HTMLElement[]|null} 创建的单个或多个标签元素
|
35
36
|
*/
|
36
37
|
function create(html) {
|
37
|
-
// 创建元素
|
38
|
-
TEMP.innerHTML = html;
|
39
|
-
let element;
|
40
|
-
if (TEMP.childElementCount == 1) {
|
41
|
-
element = TEMP.children[0];
|
42
|
-
element.remove();
|
43
|
-
} else
|
44
|
-
if (TEMP.childElementCount > 1) {
|
45
|
-
element = new Array();
|
46
|
-
do {
|
47
|
-
element.push(TEMP.children[0]);
|
48
|
-
TEMP.children[0].remove();
|
49
|
-
} while (TEMP.childElementCount > 0);
|
50
|
-
}
|
51
|
-
return element;
|
52
|
-
|
53
38
|
// DocumentFragment
|
39
|
+
// 插入文档即便多个标签也仅触发一次重渲染
|
40
|
+
// 插入后实例为空集合
|
41
|
+
// Element.innerHTML
|
42
|
+
|
43
|
+
if (html) {
|
44
|
+
if (html.trim) {
|
45
|
+
// 创建新元素
|
46
|
+
TEMPLATE.innerHTML = html;
|
47
|
+
if (TEMPLATE.content.childElementCount == 1) {
|
48
|
+
return TEMPLATE.content.firstElementChild;
|
49
|
+
} else
|
50
|
+
if (TEMPLATE.content.childElementCount > 1) {
|
51
|
+
return Array.from(TEMPLATE.content.children);
|
52
|
+
}
|
53
|
+
} else
|
54
|
+
if (html.tagName) {
|
55
|
+
// 已为元素实例
|
56
|
+
// 添加到临时集合以便渲染
|
57
|
+
TEMPLATE.innerHTML = "";
|
58
|
+
TEMPLATE.appendChild(html);
|
59
|
+
return html;
|
60
|
+
} else
|
61
|
+
if (html instanceof DocumentFragment) {
|
62
|
+
// 已为元素实例
|
63
|
+
// 添加到临时集合以便渲染
|
64
|
+
TEMPLATE.innerHTML = "";
|
65
|
+
TEMPLATE.appendChild(html);
|
66
|
+
return Array.from(TEMPLATE.content.children);
|
67
|
+
}
|
68
|
+
}
|
69
|
+
return null;
|
54
70
|
}
|
55
71
|
|
56
72
|
/**
|
57
73
|
* 创建并添加标签元素
|
58
|
-
* @param {
|
59
|
-
* @param {String}
|
60
|
-
* @
|
74
|
+
* @param {HTMLElement} element 父标签元素
|
75
|
+
* @param {String} selector 选择器字符串
|
76
|
+
* @param {HTMLElement|String} html 要添加的标签元素实例或HTML字符串
|
77
|
+
* @return {HTMLElement|HTMLElement[]|null} 创建的单个/多个标签元素/null
|
78
|
+
* @example eno.append(html); //添加到文档尾部
|
79
|
+
* @example eno.append(element,html); // 添加到指定标签尾部
|
80
|
+
* @example eno.append(element,selector,html); // 添加到指定标签中匹配选择器的标签尾部
|
61
81
|
*/
|
62
|
-
function append(element, html) {
|
82
|
+
function append(element, selector, html) {
|
63
83
|
if (arguments.length == 1) {
|
64
84
|
// append(html);
|
65
|
-
html = element;
|
85
|
+
html = create(element);
|
66
86
|
element = document.body;
|
67
87
|
} else
|
68
88
|
if (arguments.length == 2) {
|
89
|
+
// append(element,selector); 无效
|
69
90
|
// append(element,html);
|
91
|
+
// append(selector,html);
|
70
92
|
element = select(element);
|
93
|
+
html = create(selector);
|
94
|
+
} else
|
95
|
+
if (arguments.length == 3) {
|
96
|
+
// append(element,selector,html)
|
97
|
+
element = select(element, selector);
|
98
|
+
html = create(html);
|
71
99
|
} else {
|
72
100
|
return null;
|
73
101
|
}
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
}
|
78
|
-
if (Array.isArray(html)) {
|
79
|
-
for (let i = 0; i < html.length; i++) {
|
80
|
-
element.appendChild(html[i]);
|
81
|
-
}
|
82
|
-
} else {
|
83
|
-
element.appendChild(html);
|
84
|
-
}
|
102
|
+
|
103
|
+
if (element && html) {
|
104
|
+
element.appendChild(TEMPLATE.content);
|
85
105
|
return html;
|
86
106
|
}
|
87
107
|
return null;
|
@@ -89,673 +109,760 @@ function append(element, html) {
|
|
89
109
|
|
90
110
|
/**
|
91
111
|
* 创建并替换为标签元素
|
92
|
-
* @param {
|
93
|
-
* @param {String}
|
94
|
-
* @
|
112
|
+
* @param {HTMLElement} element 目标标签元素
|
113
|
+
* @param {String} selector 选择器字符串
|
114
|
+
* @param {HTMLElement|String} html 用于替换的标签元素或HTML字符串
|
115
|
+
* @return {HTMLElement|HTMLElement[]|null} 创建的单个/多个标签元素/null
|
116
|
+
* @example eno.replace(element,html);
|
117
|
+
* @example eno.replace(element,selector,html);
|
95
118
|
*/
|
96
|
-
function replace(element, html) {
|
119
|
+
function replace(element, selector, html) {
|
97
120
|
if (arguments.length == 2) {
|
121
|
+
// replace(element,html);
|
122
|
+
// replace(selector,html);
|
98
123
|
element = select(element);
|
124
|
+
html = create(selector);
|
125
|
+
} else
|
126
|
+
if (arguments.length == 3) {
|
127
|
+
// replace(element,selector,html);
|
128
|
+
element = select(element, selector);
|
129
|
+
html = create(html);
|
99
130
|
} else {
|
100
131
|
return null;
|
101
132
|
}
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
for (let i = 0; i < html.length; i++) {
|
110
|
-
item = html[i];
|
111
|
-
if (element.className) {
|
112
|
-
item.className += " " + element.className;
|
113
|
-
}
|
114
|
-
if (element.style.cssText) {
|
115
|
-
item.style.cssText += element.style.cssText;
|
116
|
-
}
|
117
|
-
}
|
118
|
-
element.replaceWith(html);
|
119
|
-
} else {
|
120
|
-
if (element.className) {
|
121
|
-
html.className += " " + element.className;
|
122
|
-
}
|
133
|
+
|
134
|
+
if (element && html) {
|
135
|
+
// 转移属性
|
136
|
+
if (Array.isArray(html)) {
|
137
|
+
for (let i = 0; i < html.length; i++) {
|
138
|
+
// TODO 需要测试验证
|
139
|
+
html[i].classList.add(element.classList);
|
123
140
|
if (element.style.cssText) {
|
124
|
-
html.style.cssText += element.style.cssText;
|
141
|
+
html[i].style.cssText += element.style.cssText;
|
125
142
|
}
|
126
|
-
|
143
|
+
}
|
144
|
+
} else {
|
145
|
+
// TODO 需要测试验证
|
146
|
+
html.classList.add(element.classList);
|
147
|
+
if (element.style.cssText) {
|
148
|
+
html.style.cssText += element.style.cssText;
|
127
149
|
}
|
128
150
|
}
|
151
|
+
element.replaceWith(TEMPLATE.content);
|
129
152
|
return html;
|
130
153
|
}
|
131
154
|
return null;
|
132
155
|
}
|
133
156
|
|
134
157
|
/**
|
135
|
-
*
|
136
|
-
* @
|
137
|
-
* @
|
138
|
-
* @
|
158
|
+
* 在指定范围内/整个文档查找标签元素
|
159
|
+
* @example eno.select(selector);
|
160
|
+
* @example eno.select(element,selector);
|
161
|
+
* @param {HTMLElement} element 要在其中查找的父标签元素
|
162
|
+
* @param {String} selector 选择器字符串
|
163
|
+
* @return {HTMLElement|null} 匹配的单个标签元素,如果匹配多个仅返回第一个
|
139
164
|
*/
|
140
165
|
function select(element, selector) {
|
141
166
|
if (arguments.length == 1) {
|
142
167
|
// 仅指定1个参数
|
143
|
-
// select(element
|
168
|
+
// select(element);
|
169
|
+
// select(selector);
|
170
|
+
if (element.tagName) {
|
171
|
+
return element;
|
172
|
+
} else
|
144
173
|
if (element.trim) {
|
145
|
-
|
146
|
-
if (element.length == 0) {
|
147
|
-
return null;
|
148
|
-
}
|
149
|
-
if (element.length == 1) {
|
150
|
-
return element[0];
|
151
|
-
}
|
152
|
-
return Array.from(element);
|
174
|
+
return document.querySelector(element);
|
153
175
|
} else
|
154
|
-
if (element.
|
155
|
-
|
176
|
+
if (element.length) {
|
177
|
+
// NodeList,HTMLCollection
|
178
|
+
return element[0];
|
156
179
|
}
|
157
180
|
} else
|
158
181
|
if (arguments.length == 2) {
|
159
182
|
// 指定了2个参数
|
160
183
|
// select(element, selector);
|
161
|
-
if (element.
|
162
|
-
element
|
163
|
-
if (element.length == 0) {
|
164
|
-
return null;
|
165
|
-
}
|
166
|
-
} else
|
167
|
-
if (element.nodeType) {
|
168
|
-
element = element.querySelectorAll(selector);
|
169
|
-
if (element.length == 0) {
|
170
|
-
return null;
|
171
|
-
}
|
172
|
-
if (element.length == 1) {
|
173
|
-
return element[0];
|
174
|
-
}
|
175
|
-
return Array.from(element);
|
184
|
+
if (element.tagName) {
|
185
|
+
return element.querySelector(selector);
|
176
186
|
} else
|
177
|
-
if (
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
}
|
182
|
-
// element[]
|
183
|
-
let nodes, items = new Array();
|
184
|
-
for (let i = 0; i < element.length; i++) {
|
185
|
-
nodes = element[i].querySelectorAll(selector);
|
186
|
-
for (let n = 0; n < nodes.length; n++) {
|
187
|
-
items.push(nodes[n]);
|
187
|
+
if (element.trim) {
|
188
|
+
element = document.querySelector(element);
|
189
|
+
if (element) {
|
190
|
+
return element.querySelector(selector);
|
188
191
|
}
|
189
192
|
}
|
190
|
-
|
191
|
-
|
192
|
-
}
|
193
|
-
if (items.length == 1) {
|
194
|
-
return items[0];
|
195
|
-
}
|
196
|
-
return items;
|
193
|
+
// 不支持element参数为数组或集合
|
194
|
+
// 应用场景极少且让程序难以理解
|
197
195
|
}
|
196
|
+
return null;
|
198
197
|
}
|
199
198
|
|
200
199
|
/**
|
201
|
-
*
|
202
|
-
* @
|
203
|
-
* @
|
204
|
-
* @
|
200
|
+
* 在指定范围内/整个文档查找标签元素
|
201
|
+
* @example eno.selects(selector);
|
202
|
+
* @example eno.selects(element,selector);
|
203
|
+
* @param {HTMLElement} element 要在其中查找的父标签元素
|
204
|
+
* @param {String} selector 选择器字符串
|
205
|
+
* @return {HTMLElement[]|null} 匹配的多个标签元素,仅匹配一个也返回数组
|
205
206
|
*/
|
206
207
|
function selects(element, selector) {
|
207
208
|
if (arguments.length == 1) {
|
208
209
|
// 仅指定1个参数
|
209
|
-
// selects(
|
210
|
+
// selects(selector);
|
211
|
+
if (element.tagName) {
|
212
|
+
// 仅提供元素参数
|
213
|
+
return [element];
|
214
|
+
} else
|
210
215
|
if (element.trim) {
|
211
216
|
// 仅提供字符串参数
|
212
217
|
element = document.querySelectorAll(element);
|
213
|
-
if (element.length
|
214
|
-
return
|
218
|
+
if (element.length > 0) {
|
219
|
+
return Array.from(element);
|
215
220
|
}
|
216
|
-
return Array.from(element);
|
217
221
|
} else
|
218
|
-
if (element.
|
219
|
-
//
|
220
|
-
return
|
222
|
+
if (element.length) {
|
223
|
+
// NodeList,HTMLCollection
|
224
|
+
return Array.from(element);
|
221
225
|
}
|
222
226
|
} else
|
223
227
|
if (arguments.length == 2) {
|
224
228
|
// 指定了2个参数
|
225
229
|
// select(element, selector);
|
226
|
-
if (element.
|
227
|
-
element = document.querySelectorAll(element);
|
228
|
-
if (element.length == 0) {
|
229
|
-
return null;
|
230
|
-
}
|
231
|
-
} else
|
232
|
-
if (element.nodeType) {
|
230
|
+
if (element.tagName) {
|
233
231
|
element = element.querySelectorAll(selector);
|
234
|
-
if (element.length
|
235
|
-
return
|
232
|
+
if (element.length > 0) {
|
233
|
+
return Array.from(element);
|
236
234
|
}
|
237
|
-
return Array.from(element);
|
238
235
|
} else
|
239
|
-
if (
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
for (let i = 0; i < element.length; i++) {
|
246
|
-
nodes = element[i].querySelectorAll(selector);
|
247
|
-
for (let n = 0; n < nodes.length; n++) {
|
248
|
-
items.push(nodes[n]);
|
236
|
+
if (element.trim) {
|
237
|
+
element = document.querySelector(element);
|
238
|
+
if (element) {
|
239
|
+
element = element.querySelectorAll(selector);
|
240
|
+
if (element.length > 0) {
|
241
|
+
return Array.from(element);
|
249
242
|
}
|
250
243
|
}
|
251
|
-
if (items.length == 0) {
|
252
|
-
return null;
|
253
|
-
}
|
254
|
-
return items;
|
255
244
|
}
|
245
|
+
// 不支持element参数为数组或集合
|
246
|
+
// 应用场景极少且让程序难以理解
|
256
247
|
}
|
248
|
+
return null;
|
257
249
|
}
|
258
250
|
|
259
251
|
/**
|
260
|
-
*
|
261
|
-
* @param {
|
262
|
-
* @param {String} selector
|
263
|
-
* @return {Element} 移除的单个/多个标签元素
|
252
|
+
* 从文档移除标签元素
|
253
|
+
* @param {HTMLElement} element 要在其中查找的父标签元素
|
254
|
+
* @param {String} selector 选择器字符串
|
264
255
|
*/
|
265
256
|
function remove(element, selector) {
|
266
257
|
if (arguments.length == 1) {
|
267
|
-
element =
|
258
|
+
element = selects(element);
|
268
259
|
} else
|
269
260
|
if (arguments.length == 2) {
|
270
|
-
element =
|
261
|
+
element = selects(element, selector);
|
271
262
|
} else {
|
272
263
|
return;
|
273
264
|
}
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
}
|
279
|
-
} else {
|
280
|
-
element.remove();
|
265
|
+
|
266
|
+
if (element && element.length) {
|
267
|
+
for (let i = 0; i < element.length; i++) {
|
268
|
+
element[i].remove();
|
281
269
|
}
|
282
270
|
}
|
283
|
-
return element;
|
284
271
|
}
|
285
272
|
|
286
273
|
/**
|
287
|
-
*
|
288
|
-
* @param {
|
289
|
-
* @param {String} selector
|
290
|
-
* @return {Element} 隐藏的单个/多个标签元素
|
274
|
+
* 隐藏标签元素
|
275
|
+
* @param {HTMLElement} element 要在其中查找的父标签元素
|
276
|
+
* @param {String} selector 选择器字符串
|
291
277
|
*/
|
292
278
|
function hide(element, selector) {
|
293
279
|
if (arguments.length == 1) {
|
294
|
-
element =
|
280
|
+
element = selects(element);
|
295
281
|
} else
|
296
282
|
if (arguments.length == 2) {
|
297
|
-
element =
|
283
|
+
element = selects(element, selector);
|
298
284
|
} else {
|
299
285
|
return;
|
300
286
|
}
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
e = element[i];
|
306
|
-
if (e.hidden) {} else {
|
307
|
-
e.hidden = true;
|
308
|
-
e.__DISPLAY = e.style.display
|
309
|
-
e.style.display = "none";
|
310
|
-
}
|
311
|
-
}
|
312
|
-
} else {
|
313
|
-
if (element.hidden) {} else {
|
314
|
-
element.hidden = true;
|
315
|
-
element.__DISPLAY = element.style.display;
|
316
|
-
// display:flex 导致 hidden 属性失效而不会隐藏
|
317
|
-
element.style.display = "none";
|
318
|
-
}
|
287
|
+
|
288
|
+
if (element && element.length) {
|
289
|
+
for (let i = 0; i < element.length; i++) {
|
290
|
+
hideElement(element[i]);
|
319
291
|
}
|
320
292
|
}
|
321
|
-
return element;
|
322
293
|
}
|
323
294
|
|
324
295
|
/**
|
325
|
-
*
|
326
|
-
* @param {
|
327
|
-
* @param {String} selector
|
328
|
-
* @return {Element} 显示的单个/多个标签元素
|
296
|
+
* 显示标签元素
|
297
|
+
* @param {HTMLElement} element 要在其中查找的父标签元素
|
298
|
+
* @param {String} selector 选择器字符串
|
329
299
|
*/
|
330
300
|
function show(element, selector) {
|
331
301
|
if (arguments.length == 1) {
|
332
|
-
element =
|
302
|
+
element = selects(element);
|
333
303
|
} else
|
334
304
|
if (arguments.length == 2) {
|
335
|
-
element =
|
305
|
+
element = selects(element, selector);
|
336
306
|
} else {
|
337
307
|
return;
|
338
308
|
}
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
309
|
+
|
310
|
+
if (element && element.length) {
|
311
|
+
for (let i = 0; i < element.length; i++) {
|
312
|
+
showElement(element[i]);
|
313
|
+
}
|
314
|
+
}
|
315
|
+
}
|
316
|
+
|
317
|
+
function hideElement(element) {
|
318
|
+
if (element.hidden) {
|
319
|
+
if (element.__ENO_DISPLAY !== undefined) {
|
320
|
+
return;
|
321
|
+
}
|
322
|
+
} else {
|
323
|
+
element.hidden = true;
|
324
|
+
}
|
325
|
+
// display:flex 导致 hidden 属性失效而不会隐藏
|
326
|
+
element.__ENO_DISPLAY = element.style.display;
|
327
|
+
element.style.display = "none";
|
328
|
+
}
|
329
|
+
|
330
|
+
function showElement(element) {
|
331
|
+
if (element.hidden) {
|
332
|
+
element.hidden = false;
|
333
|
+
if (element.__ENO_DISPLAY !== undefined) {
|
334
|
+
element.style.display = element.__ENO_DISPLAY;
|
353
335
|
}
|
354
336
|
}
|
355
|
-
return element;
|
356
337
|
}
|
357
338
|
|
358
339
|
/**
|
359
340
|
* 切换指定元素显示,同级其余元素隐藏;
|
360
|
-
*
|
361
|
-
* @param {
|
362
|
-
* @param {String} selector
|
363
|
-
* @param {String} applyClass 添加类名称,必须同时提供otherClass
|
364
|
-
* @param {String} otherClass 移除类名称,必须同时提供applyClass
|
365
|
-
* @return {
|
341
|
+
* 如果指定样式类名,则当前元素添加样式类,其余元素移除样式类,样式类名区分大小写
|
342
|
+
* @param {HTMLElement} element 要在其中查找的父标签元素
|
343
|
+
* @param {String} selector 选择器字符串
|
344
|
+
* @param {String} applyClass 添加类名称,必须同时提供otherClass参数,可指定""/null表示无具体类名
|
345
|
+
* @param {String} otherClass 移除类名称,必须同时提供applyClass参数,可指定""/null表示无具体类名
|
346
|
+
* @return {HTMLElement|HTMLElement[]|null} 显示的单个/多个标签元素
|
366
347
|
*/
|
367
348
|
function toggle(element, selector, applyClass, otherClass) {
|
368
349
|
if (arguments.length == 1) {
|
369
350
|
// toggle(element)
|
370
|
-
element =
|
351
|
+
element = selects(element);
|
352
|
+
if (element) {
|
353
|
+
toggleElements(element);
|
354
|
+
return element;
|
355
|
+
}
|
371
356
|
} else
|
372
357
|
if (arguments.length == 2) {
|
373
358
|
// toggle(element,selector)
|
374
|
-
|
359
|
+
// toggle(element,applyClass) 无效
|
360
|
+
element = selects(element, selector);
|
361
|
+
if (element) {
|
362
|
+
toggleElements(element);
|
363
|
+
return element;
|
364
|
+
}
|
375
365
|
} else
|
376
366
|
if (arguments.length == 3) {
|
367
|
+
// toggle(element,selector,applyClass) 无效
|
377
368
|
// toggle(element,applyClass,otherClass)
|
378
|
-
element =
|
379
|
-
|
380
|
-
|
369
|
+
element = selects(element);
|
370
|
+
if (element) {
|
371
|
+
toggleClasses(element, selector, applyClass);
|
372
|
+
return element;
|
373
|
+
}
|
381
374
|
} else
|
382
375
|
if (arguments.length == 4) {
|
383
376
|
// toggle(element,selector,applyClass,otherClass)
|
384
|
-
element =
|
385
|
-
|
386
|
-
|
377
|
+
element = selects(element, selector);
|
378
|
+
if (element) {
|
379
|
+
toggleClasses(element, applyClass, otherClass);
|
380
|
+
return element;
|
381
|
+
}
|
387
382
|
}
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
383
|
+
return null;
|
384
|
+
}
|
385
|
+
|
386
|
+
function toggleElement(element) {
|
387
|
+
const parent = element.parentElement;
|
388
|
+
for (let i = 0; i < parent.children.length; i++) {
|
389
|
+
if (element !== parent.children[i]) {
|
390
|
+
hideElement(parent.children[i]);
|
391
|
+
}
|
392
|
+
}
|
393
|
+
showElement(element);
|
394
|
+
}
|
395
|
+
|
396
|
+
function toggleElements(elements) {
|
397
|
+
// 这些元素可能不在同级
|
398
|
+
let element, parent, i;
|
399
|
+
for (let e = 0; e < elements.length; e++) {
|
400
|
+
element = elements[e];
|
401
|
+
if (element.parentElement !== parent) {
|
402
|
+
parent = element.parentElement;
|
403
|
+
for (i = 0; i < parent.children.length; i++) {
|
404
|
+
if (element !== parent.children[i]) {
|
405
|
+
hideElement(parent.children[i]);
|
398
406
|
}
|
399
407
|
}
|
400
|
-
}
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
408
|
+
}
|
409
|
+
showElement(element);
|
410
|
+
}
|
411
|
+
}
|
412
|
+
|
413
|
+
function toggleClass(element, apply, other) {
|
414
|
+
const parent = element.parentElement;
|
415
|
+
for (let i = 0; i < parent.children.length; i++) {
|
416
|
+
if (element !== parent.children[i]) {
|
417
|
+
parent.children[i].classList.remove(apply);
|
418
|
+
parent.children[i].classList.add(other);
|
419
|
+
}
|
420
|
+
}
|
421
|
+
element.classList.remove(other);
|
422
|
+
element.classList.add(apply);
|
423
|
+
}
|
424
|
+
|
425
|
+
function toggleClasses(elements, apply, other) {
|
426
|
+
// 这些元素可能不在同级
|
427
|
+
let element, parent, i;
|
428
|
+
for (let e = 0; e < elements.length; e++) {
|
429
|
+
element = elements[e];
|
430
|
+
if (element.parentElement !== parent) {
|
431
|
+
parent = element.parentElement;
|
432
|
+
for (i = 0; i < parent.children.length; i++) {
|
433
|
+
if (element !== parent.children[i]) {
|
434
|
+
parent.children[i].classList.remove(apply);
|
435
|
+
parent.children[i].classList.add(other);
|
406
436
|
}
|
407
437
|
}
|
408
438
|
}
|
439
|
+
element.classList.remove(other);
|
440
|
+
element.classList.add(apply);
|
409
441
|
}
|
410
|
-
return element;
|
411
442
|
}
|
412
443
|
|
413
444
|
// 默认转换函数
|
414
|
-
function defaultConverter(element,
|
445
|
+
function defaultConverter(element, entity, name) {}
|
415
446
|
|
416
447
|
/**
|
417
|
-
*
|
418
|
-
* @param {
|
419
|
-
* @param {String} selector
|
420
|
-
* @param {Function} converter
|
421
|
-
* @return {Object}
|
448
|
+
* 从指定元素获取值以实体对象返回
|
449
|
+
* @param {HTMLElement} element 要在其中查找的父标签元素
|
450
|
+
* @param {String} selector 选择器字符串
|
451
|
+
* @param {Function} converter 转换方法
|
452
|
+
* @return {Object} 包含数据的实体对象实例
|
453
|
+
*/
|
454
|
+
function get(element, selector, converter = defaultConverter) {
|
455
|
+
if (arguments.length == 1) {
|
456
|
+
// get(element)
|
457
|
+
// get(selector)
|
458
|
+
element = select(element);
|
459
|
+
} else
|
460
|
+
if (arguments.length == 2) {
|
461
|
+
// get(element,selector)
|
462
|
+
// get(element,converter)
|
463
|
+
if (selector instanceof Function) {
|
464
|
+
element = select(element);
|
465
|
+
converter = selector;
|
466
|
+
} else {
|
467
|
+
element = select(element, selector);
|
468
|
+
}
|
469
|
+
} else
|
470
|
+
if (arguments.length == 3) {
|
471
|
+
// get(element,selector,converter)
|
472
|
+
element = select(element, selector);
|
473
|
+
} else {
|
474
|
+
return null;
|
475
|
+
}
|
476
|
+
|
477
|
+
if (element) {
|
478
|
+
let entity = {};
|
479
|
+
getEntity(element, entity, converter);
|
480
|
+
return entity;
|
481
|
+
}
|
482
|
+
return null;
|
483
|
+
}
|
484
|
+
|
485
|
+
/**
|
486
|
+
* 从指定元素获取值以JSON对象返回
|
487
|
+
* @param {HTMLElement} element 要在其中查找的父标签元素
|
488
|
+
* @param {String} selector 选择器字符串
|
489
|
+
* @param {Function} converter 转换方法
|
490
|
+
* @return {Object[]} 包含数据的实体对象实例
|
422
491
|
*/
|
423
492
|
function gets(element, selector, converter = defaultConverter) {
|
424
493
|
if (arguments.length == 1) {
|
425
494
|
// gets(element)
|
426
495
|
// gets(selector)
|
427
|
-
element =
|
496
|
+
element = selects(element);
|
428
497
|
} else
|
429
498
|
if (arguments.length == 2) {
|
430
499
|
// gets(element,selector)
|
431
500
|
// gets(element,converter)
|
432
|
-
if (selector
|
433
|
-
element =
|
434
|
-
} else {
|
435
|
-
element = select(element);
|
501
|
+
if (selector instanceof Function) {
|
502
|
+
element = selects(element);
|
436
503
|
converter = selector;
|
504
|
+
} else {
|
505
|
+
element = selects(element, selector);
|
437
506
|
}
|
438
507
|
} else
|
439
508
|
if (arguments.length == 3) {
|
440
509
|
// gets(element,selector,converter)
|
441
|
-
element =
|
510
|
+
element = selects(element, selector);
|
442
511
|
} else {
|
443
|
-
return;
|
512
|
+
return null;
|
444
513
|
}
|
514
|
+
|
445
515
|
if (element) {
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
if (Object.keys(parameter).length) {
|
452
|
-
parameters.push(parameter);
|
453
|
-
parameter = {};
|
454
|
-
}
|
455
|
-
}
|
456
|
-
return parameters;
|
457
|
-
} else {
|
458
|
-
let parameter = {};
|
459
|
-
get(element, parameter, converter);
|
460
|
-
return parameter;
|
516
|
+
let entity, entities = new Array();
|
517
|
+
for (let i = 0; i < element.length; i++) {
|
518
|
+
entity = {};
|
519
|
+
getEntity(element[i], entity, converter);
|
520
|
+
entities.push(entity);
|
461
521
|
}
|
522
|
+
return entities;
|
462
523
|
}
|
524
|
+
return null;
|
463
525
|
}
|
464
526
|
|
465
527
|
/**
|
466
|
-
*
|
467
|
-
* @param {
|
468
|
-
* @param {String} selector
|
469
|
-
* @param {Object}
|
470
|
-
* @param {Function} converter
|
471
|
-
* @return {
|
528
|
+
* 实体对象设置到标签元素显示,以name属性作为标识
|
529
|
+
* @param {HTMLElement} element 要在其中查找的父标签元素
|
530
|
+
* @param {String} selector 选择器字符串
|
531
|
+
* @param {Object} entity 数据实体对象
|
532
|
+
* @param {Function} converter 数据转换方法
|
533
|
+
* @return {HTMLElement} 设置或创建的标签元素
|
472
534
|
*/
|
473
|
-
function
|
535
|
+
function set(element, selector, entity, converter = defaultConverter) {
|
536
|
+
// 仅对单个标签元素目标
|
537
|
+
// 多个标签元素目标难以理解
|
538
|
+
|
474
539
|
if (arguments.length == 2) {
|
475
|
-
//
|
476
|
-
//
|
540
|
+
// set(element,entity)
|
541
|
+
// set(selector,entity)
|
477
542
|
element = select(element);
|
478
|
-
|
543
|
+
entity = selector;
|
479
544
|
} else
|
480
545
|
if (arguments.length == 3) {
|
481
|
-
//
|
482
|
-
//
|
483
|
-
if (
|
484
|
-
element = select(element
|
546
|
+
// set(element,selector,entity)
|
547
|
+
// set(element,entity,converter)
|
548
|
+
if (entity instanceof Function) {
|
549
|
+
element = select(element);
|
550
|
+
converter = entity;
|
551
|
+
entity = selector;
|
485
552
|
} else {
|
553
|
+
element = select(element, selector);
|
554
|
+
}
|
555
|
+
} else
|
556
|
+
if (arguments.length == 4) {
|
557
|
+
// set(element,selector,entity,converter)
|
558
|
+
element = select(element, selector);
|
559
|
+
} else {
|
560
|
+
return null;
|
561
|
+
}
|
562
|
+
|
563
|
+
if (element) {
|
564
|
+
// Object -> Element
|
565
|
+
if (Array.isArray(entity)) {
|
566
|
+
entity = entity[0];
|
567
|
+
}
|
568
|
+
|
569
|
+
setEntity(element, entity, converter);
|
570
|
+
element.__ENO_ENTITY = entity;
|
571
|
+
return element;
|
572
|
+
}
|
573
|
+
}
|
574
|
+
|
575
|
+
/**
|
576
|
+
* 实体对象设置到标签元素显示,以name属性作为标识
|
577
|
+
* @param {HTMLElement} element 要在其中查找的父标签元素
|
578
|
+
* @param {String} selector 选择器字符串
|
579
|
+
* @param {Object} entity 数据实体对象
|
580
|
+
* @param {Function} converter 数据转换方法
|
581
|
+
* @return {HTMLElement} 设置或创建的标签元素
|
582
|
+
*/
|
583
|
+
function sets(element, selector, entity, converter = defaultConverter) {
|
584
|
+
// 仅对单个标签元素目标
|
585
|
+
// 多个标签元素目标难以理解
|
586
|
+
// entity为数组时返回数组
|
587
|
+
|
588
|
+
if (arguments.length == 2) {
|
589
|
+
// sets(element,entity)
|
590
|
+
// sets(selector,entity)
|
591
|
+
element = select(element);
|
592
|
+
entity = selector;
|
593
|
+
} else
|
594
|
+
if (arguments.length == 3) {
|
595
|
+
// sets(element,selector,entity)
|
596
|
+
// sets(element,entity,converter)
|
597
|
+
if (entity instanceof Function) {
|
486
598
|
element = select(element);
|
487
|
-
converter =
|
488
|
-
|
599
|
+
converter = entity;
|
600
|
+
entity = selector;
|
601
|
+
} else {
|
602
|
+
element = select(element, selector);
|
489
603
|
}
|
490
604
|
} else
|
491
605
|
if (arguments.length == 4) {
|
492
|
-
// sets(element,selector,
|
606
|
+
// sets(element,selector,entity,converter)
|
493
607
|
element = select(element, selector);
|
494
608
|
} else {
|
495
|
-
return;
|
609
|
+
return null;
|
496
610
|
}
|
611
|
+
|
497
612
|
if (element) {
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
}
|
613
|
+
// Object[] -> Element.children
|
614
|
+
let i = 0;
|
615
|
+
// 利用ENO_SET缓存模板并判定是否首次
|
616
|
+
if (element.__ENO_SETS === undefined) {
|
617
|
+
if (element.childElementCount) {
|
618
|
+
element.__ENO_SETS = {};
|
619
|
+
// 查找模块和位置
|
620
|
+
// before...<template>...after
|
621
|
+
// 只有<template>模板具有content属性
|
622
|
+
// 记录模板前后已有标签元素数量
|
623
|
+
// before数量包括模板本身
|
624
|
+
for (i = 0; i < element.childElementCount; i++) {
|
625
|
+
if (element.children[i].content) {
|
626
|
+
element.__ENO_SETS.fragment = element.children[i].content;
|
627
|
+
element.__ENO_SETS.before = ++i;
|
628
|
+
element.__ENO_SETS.after = element.childElementCount - i;
|
629
|
+
break;
|
516
630
|
}
|
517
631
|
}
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
for (i = 0; i < parameter.length; i++) {
|
525
|
-
if (element.__ENO_SETS.before + i < element.childElementCount - element.__ENO_SETS.after) {
|
526
|
-
// 重用已有元素
|
527
|
-
for (n = 0; n < element.__ENO_SETS.template.content.childElementCount; n++) {
|
528
|
-
node = element.children[element.__ENO_SETS.before + i + n];
|
529
|
-
set(node, parameter[i], converter);
|
530
|
-
node.userData = parameter[i];
|
531
|
-
}
|
532
|
-
} else {
|
533
|
-
// 克隆新的元素(DocumentFragment)
|
534
|
-
// node = element.template.content.cloneNode(true);
|
535
|
-
node = document.importNode(element.__ENO_SETS.template.content, true);
|
536
|
-
for (n = 0; n < node.childElementCount; n++) {
|
537
|
-
set(node.children.item(n), parameter[i], converter);
|
538
|
-
node.children.item(n).userData = parameter[i];
|
539
|
-
}
|
540
|
-
element.insertBefore(node, element.children[element.__ENO_SETS.before + i * node.childElementCount]);
|
541
|
-
}
|
542
|
-
}
|
543
|
-
// 移除多余元素
|
544
|
-
n = i * element.__ENO_SETS.template.content.childElementCount;
|
545
|
-
i = element.__ENO_SETS.before + element.__ENO_SETS.after;
|
546
|
-
while (element.childElementCount > i + n) {
|
547
|
-
element.children[element.__ENO_SETS.before + n].remove();
|
548
|
-
}
|
549
|
-
return element;
|
550
|
-
} else {
|
551
|
-
// 移除多余元素
|
552
|
-
i = element.__ENO_SETS.before + element.__ENO_SETS.after;
|
553
|
-
while (element.childElementCount > i) {
|
554
|
-
element.children[element.childElementCount - element.__ENO_SETS.after - 1].remove();
|
555
|
-
}
|
556
|
-
return element;
|
557
|
-
}
|
558
|
-
} else {
|
559
|
-
// 未使用模板
|
560
|
-
if (parameter.length) {
|
561
|
-
let node;
|
562
|
-
// 构造填充元素
|
563
|
-
for (i = 0; i < parameter.length; i++) {
|
564
|
-
if (i < element.childElementCount) {
|
565
|
-
// 重用已有元素
|
566
|
-
node = element.children[i];
|
567
|
-
} else if (node) {
|
568
|
-
// 克隆新的元素
|
569
|
-
node = element.appendChild(node.cloneNode(true));
|
570
|
-
} else {
|
571
|
-
// 干不了
|
572
|
-
// 此情形出现于没有任何子标签元素
|
573
|
-
continue;
|
574
|
-
}
|
575
|
-
set(node, parameter[i], converter);
|
576
|
-
node.userData = parameter[i];
|
577
|
-
node.hidden = false;
|
578
|
-
}
|
579
|
-
// 移除多余元素
|
580
|
-
while (element.childElementCount > i) {
|
581
|
-
element.children[i].remove();
|
582
|
-
}
|
583
|
-
return element;
|
584
|
-
} else {
|
585
|
-
// 移除多余元素,保留模板
|
586
|
-
element.children[0].userData = null;
|
587
|
-
element.children[0].hidden = true;
|
588
|
-
while (element.childElementCount > 1) {
|
589
|
-
element.children[1].remove();
|
590
|
-
}
|
591
|
-
return element;
|
632
|
+
// 未定义模板<template>
|
633
|
+
// 子元素视为模板
|
634
|
+
if (element.__ENO_SETS.fragment === undefined) {
|
635
|
+
element.__ENO_SETS.fragment = new DocumentFragment();
|
636
|
+
while (element.childElementCount > 0) {
|
637
|
+
element.__ENO_SETS.fragment.appendChild(element.children[0]);
|
592
638
|
}
|
639
|
+
element.__ENO_SETS.before = 0;
|
640
|
+
element.__ENO_SETS.after = 0;
|
593
641
|
}
|
594
642
|
} else {
|
595
|
-
//
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
643
|
+
// 没有可用模板
|
644
|
+
return null;
|
645
|
+
}
|
646
|
+
}
|
647
|
+
if (entity) {
|
648
|
+
if (!Array.isArray(entity)) {
|
649
|
+
entity = [entity];
|
650
|
+
}
|
651
|
+
|
652
|
+
let node, n;
|
653
|
+
// 构造填充元素
|
654
|
+
for (i = 0; i < entity.length; i++) {
|
655
|
+
if (element.__ENO_SETS.before + i < element.childElementCount - element.__ENO_SETS.after) {
|
656
|
+
// 重用已有元素
|
657
|
+
for (n = 0; n < element.__ENO_SETS.fragment.childElementCount; n++) {
|
658
|
+
node = element.children[element.__ENO_SETS.before + i + n];
|
659
|
+
setEntity(node, entity[i], converter);
|
660
|
+
node.__ENO_ENTITY = entity[i];
|
600
661
|
}
|
601
662
|
} else {
|
602
|
-
|
603
|
-
|
663
|
+
// 克隆新的元素(DocumentFragment)
|
664
|
+
node = element.__ENO_SETS.fragment.cloneNode(true);
|
665
|
+
for (n = 0; n < node.childElementCount; n++) {
|
666
|
+
setEntity(node.children[n], entity[i], converter);
|
667
|
+
node.children[n].__ENO_ENTITY = entity[i];
|
668
|
+
}
|
669
|
+
element.insertBefore(node, element.children[element.__ENO_SETS.before + i * node.childElementCount]);
|
604
670
|
}
|
605
|
-
|
671
|
+
}
|
672
|
+
// 移除多余元素
|
673
|
+
n = i * element.__ENO_SETS.fragment.childElementCount;
|
674
|
+
i = element.__ENO_SETS.before + element.__ENO_SETS.after;
|
675
|
+
while (element.childElementCount > i + n) {
|
676
|
+
element.children[element.__ENO_SETS.before + n].remove();
|
606
677
|
}
|
607
678
|
} else {
|
608
679
|
// null / undefine -> Element
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
while (element.childElementCount > i) {
|
613
|
-
element.children[element.childElementCount - element.__ENO_SETS.after - 1].remove();
|
614
|
-
}
|
615
|
-
} else {
|
616
|
-
element.children[0].userData = null;
|
617
|
-
element.children[0].hidden = true;
|
618
|
-
while (element.childElementCount > 1) {
|
619
|
-
element.children[1].remove();
|
620
|
-
}
|
621
|
-
}
|
622
|
-
} else {
|
623
|
-
if (Array.isArray(element)) {
|
624
|
-
for (let i = 0; i < element.length; i++) {
|
625
|
-
set(element[i], null, converter);
|
626
|
-
element[i].userData = null;
|
627
|
-
}
|
628
|
-
} else {
|
629
|
-
set(element, null, converter);
|
630
|
-
element.userData = null;
|
631
|
-
}
|
680
|
+
i = element.__ENO_SETS.before + element.__ENO_SETS.after;
|
681
|
+
while (element.childElementCount > i) {
|
682
|
+
element.children[element.childElementCount - element.__ENO_SETS.after - 1].remove();
|
632
683
|
}
|
633
|
-
return element;
|
634
684
|
}
|
685
|
+
return element;
|
635
686
|
}
|
636
687
|
}
|
637
688
|
|
638
689
|
/**
|
639
|
-
*
|
690
|
+
* 获取实体从标签元素
|
640
691
|
* <input name="AAA" value="123"/>
|
641
692
|
* <span name="AAA">123</span>
|
642
693
|
* <img name="AAA" src="123"/>
|
643
694
|
* <i case="AAA"></i>
|
644
695
|
*/
|
645
|
-
function
|
696
|
+
function getEntity(element, entity, converter) {
|
646
697
|
let name = element.getAttribute("case");
|
647
698
|
if (name && name.length) {
|
648
|
-
converter(element,
|
699
|
+
converter(element, entity, name);
|
649
700
|
}
|
650
701
|
name = element.getAttribute("name");
|
651
702
|
if (name && name.length) {
|
652
703
|
if (element.type) {
|
653
|
-
|
704
|
+
// 所有控件具有type属性
|
705
|
+
// 所有控件具有disabled属性
|
706
|
+
// <select> <textarea> 没有checked属性,其余均有
|
707
|
+
if (!element.disabled) {
|
708
|
+
if (element.type === "number" || element.type === "range") {
|
709
|
+
if (!isNaN(element.valueAsNumber)) {
|
710
|
+
setValue(entity, name, element.valueAsNumber);
|
711
|
+
}
|
712
|
+
} else
|
713
|
+
if (element.type === "checkbox" || element.type === "radio") {
|
714
|
+
if (element.checked) {
|
715
|
+
setValue(entity, name, element.value);
|
716
|
+
}
|
717
|
+
} else {
|
718
|
+
if (element.value) {
|
719
|
+
setValue(entity, name, element.value);
|
720
|
+
}
|
721
|
+
}
|
722
|
+
}
|
654
723
|
} else
|
655
724
|
if (element.src) {
|
656
|
-
|
725
|
+
// img
|
726
|
+
setValue(entity, name, element.src);
|
657
727
|
} else {
|
658
|
-
|
728
|
+
setValue(entity, name, element.innerText);
|
659
729
|
}
|
660
730
|
}
|
661
731
|
if (element.childElementCount) {
|
662
732
|
for (let i = 0; i < element.children.length; i++) {
|
663
|
-
|
733
|
+
getEntity(element.children[i], entity, converter);
|
664
734
|
}
|
665
735
|
}
|
666
736
|
}
|
667
737
|
|
668
738
|
/**
|
669
|
-
*
|
739
|
+
* 设置实体到标签元素
|
670
740
|
* <input name="AAA" value="123"/>
|
671
741
|
* <span name="AAA">123</span>
|
672
742
|
* <img name="AAA" src="123"/>
|
673
743
|
* <i case="AAA"></i>
|
674
744
|
*/
|
675
|
-
function
|
745
|
+
function setEntity(element, entity, converter) {
|
676
746
|
let name = element.getAttribute("case");
|
677
747
|
if (name && name.length) {
|
678
|
-
converter(element,
|
748
|
+
converter(element, entity, name);
|
679
749
|
}
|
680
750
|
name = element.getAttribute("name");
|
681
751
|
if (name && name.length) {
|
682
752
|
if (element.type) {
|
683
|
-
|
753
|
+
// 所有控件具有type属性
|
754
|
+
if (element.type === "checkbox" || element.type === "radio") {
|
755
|
+
// Radio / Check
|
756
|
+
element.checked = element.value == getValue(entity, name);
|
757
|
+
} else {
|
758
|
+
// OTHER
|
759
|
+
element.value = text(getValue(entity, name));
|
760
|
+
}
|
684
761
|
} else
|
685
|
-
if (element.src) {
|
686
|
-
|
762
|
+
if (element.src !== undefined) {
|
763
|
+
// <img />
|
764
|
+
if (element.__ENO_SRC === undefined) {
|
765
|
+
// 记录默认图像
|
766
|
+
element.__ENO_SRC = element.src;
|
767
|
+
}
|
768
|
+
element.src = text(getValue(entity, name));
|
769
|
+
if (element.src.length == 0) {
|
770
|
+
element.src = element.__ENO_SRC;
|
771
|
+
}
|
687
772
|
} else {
|
688
|
-
element.
|
773
|
+
if (element.__ENO_TEXT === undefined) {
|
774
|
+
// 原始内容作为默认值
|
775
|
+
element.__ENO_TEXT = element.innerText;
|
776
|
+
// 是否已有title
|
777
|
+
// 如果用于已设置title则不在自动设置
|
778
|
+
element.__ENO_TITLE = element.title ? false : true;
|
779
|
+
}
|
780
|
+
element.innerText = text(getValue(entity, name));
|
781
|
+
if (element.innerText.length == 0) {
|
782
|
+
element.innerText = element.__ENO_TEXT;
|
783
|
+
}
|
784
|
+
if (element.__ENO_TITLE) {
|
785
|
+
// 设置title实现文本提示
|
786
|
+
element.title = element.innerText;
|
787
|
+
}
|
689
788
|
}
|
690
789
|
}
|
691
790
|
if (element.childElementCount) {
|
692
791
|
for (let i = 0; i < element.children.length; i++) {
|
693
|
-
|
792
|
+
setEntity(element.children[i], entity, converter);
|
694
793
|
}
|
695
794
|
}
|
696
795
|
}
|
697
796
|
|
698
797
|
/**
|
699
|
-
*
|
700
|
-
* @param {Object}
|
701
|
-
* @param {Object} name
|
702
|
-
* @returns {Object}
|
798
|
+
* 根据名称获取实体对象值
|
799
|
+
* @param {Object} entity 要获取值的实体对象
|
800
|
+
* @param {Object} name 字段名称 "Device.Type.Text" 区分大小写
|
801
|
+
* @returns {Object} 获取的值
|
703
802
|
*/
|
704
|
-
function
|
803
|
+
function getValue(entity, name) {
|
705
804
|
name = name.split(".");
|
706
805
|
for (let i = 0; i < name.length; i++) {
|
707
|
-
if (
|
708
|
-
if (Array.isArray(
|
806
|
+
if (entity) {
|
807
|
+
if (Array.isArray(entity)) {
|
709
808
|
const items = new Array();
|
710
|
-
for (let a = 0; a <
|
711
|
-
if (
|
712
|
-
items.push(
|
809
|
+
for (let a = 0; a < entity.length; a++) {
|
810
|
+
if (entity[a]) {
|
811
|
+
items.push(entity[a][name[i]]);
|
713
812
|
}
|
714
813
|
}
|
715
|
-
|
814
|
+
entity = items;
|
716
815
|
} else {
|
717
|
-
|
816
|
+
entity = entity[name[i]];
|
718
817
|
}
|
719
818
|
} else {
|
720
819
|
break;
|
721
820
|
}
|
722
821
|
}
|
723
|
-
return
|
822
|
+
return entity;
|
724
823
|
}
|
725
824
|
|
726
825
|
/**
|
727
|
-
*
|
728
|
-
* @param {Object}
|
729
|
-
* @param {Object} name "Device.Type.Text"
|
730
|
-
* @param {Object} value
|
826
|
+
* 根据名称设置实体对象值
|
827
|
+
* @param {Object} entity 要设置值的实体对象
|
828
|
+
* @param {Object} name 字段名称 "Device.Type.Text" 区分大小写
|
829
|
+
* @param {Object} value 要设置的值
|
731
830
|
*/
|
732
|
-
function
|
831
|
+
function setValue(entity, name, value) {
|
733
832
|
name = name.split(".");
|
734
833
|
let i = 0;
|
735
834
|
for (; i < name.length - 1; i++) {
|
736
|
-
if (
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
835
|
+
if (entity[name[i]]) {
|
836
|
+
entity = entity[name[i]];
|
837
|
+
} else {
|
838
|
+
entity = entity[name[i]] = {};
|
839
|
+
}
|
840
|
+
}
|
841
|
+
// 点语法最后的名称
|
842
|
+
name = name[i];
|
843
|
+
// 相同name多次出现应数组化
|
844
|
+
if (entity[name] === undefined) {
|
845
|
+
entity[name] = value;
|
846
|
+
} else {
|
847
|
+
if (Array.isArray(entity[name])) {
|
848
|
+
entity[name].push(value);
|
849
|
+
} else {
|
850
|
+
entity[name] = [entity[name], value];
|
742
851
|
}
|
743
852
|
}
|
744
|
-
o[name[i]] = value;
|
745
|
-
return o;
|
746
853
|
}
|
747
854
|
|
748
855
|
/**
|
749
856
|
* 转换为字符串值
|
750
|
-
* @param {
|
857
|
+
* @param {any} value
|
751
858
|
*/
|
752
|
-
function text(
|
753
|
-
if (Array.isArray(
|
859
|
+
function text(value) {
|
860
|
+
if (Array.isArray(value)) {
|
754
861
|
// 数组值合并(逗号分割)
|
755
|
-
return
|
862
|
+
return value.join(',');
|
756
863
|
}
|
757
|
-
if (
|
758
|
-
return
|
864
|
+
if (value !== undefined && value !== null) {
|
865
|
+
return value.toString();
|
759
866
|
}
|
760
867
|
return "";
|
761
868
|
}
|
@@ -773,56 +880,58 @@ function text(o) {
|
|
773
880
|
function bind(element, selector, eventName, listener) {
|
774
881
|
if (arguments.length == 3) {
|
775
882
|
// bind(element,eventName,listener);
|
776
|
-
|
883
|
+
// bind(selector,eventName,listener);
|
884
|
+
element = selects(element);
|
777
885
|
listener = eventName;
|
778
886
|
eventName = selector;
|
779
887
|
} else
|
780
888
|
if (arguments.length == 4) {
|
781
889
|
// bind(element,selector,eventName,listener);
|
782
|
-
element =
|
890
|
+
element = selects(element, selector);
|
783
891
|
} else {
|
784
|
-
return;
|
892
|
+
return null;
|
785
893
|
}
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
}
|
791
|
-
} else {
|
792
|
-
element.addEventListener(eventName, listener);
|
894
|
+
|
895
|
+
if (element && element.length) {
|
896
|
+
for (let i = 0; i < element.length; i++) {
|
897
|
+
element[i].addEventListener(eventName, listener);
|
793
898
|
}
|
899
|
+
return element;
|
794
900
|
}
|
795
|
-
return
|
901
|
+
return null;
|
796
902
|
}
|
797
903
|
|
798
904
|
/**
|
799
|
-
*
|
905
|
+
* 根据事件或标签元素获取由eno.sets()对应的实体对象
|
906
|
+
* @param {Event|HTMLElement} e 事件或标签元素
|
907
|
+
* @param {String} selector 选择器字符串
|
908
|
+
* @return {Object} 标签元素对应的实体对象
|
800
909
|
* @example entity(event);
|
801
910
|
* @example entity(element);
|
802
911
|
* @example entity(element,selector);
|
803
|
-
* @return {Object} 标签元素关联的数据对象
|
804
912
|
*/
|
805
913
|
function entity(e, selector) {
|
806
914
|
if (arguments.length == 1) {
|
807
915
|
// entity(event);
|
808
|
-
if (e.
|
809
|
-
e = e;
|
810
|
-
} else
|
811
|
-
if (e && e.target) {
|
916
|
+
if (e.target) {
|
812
917
|
e = e.target;
|
813
918
|
} else
|
814
|
-
if (e
|
919
|
+
if (e.srcElement) {
|
815
920
|
e = e.srcElement;
|
921
|
+
} else {
|
922
|
+
e = select(e);
|
816
923
|
}
|
817
924
|
} else
|
818
925
|
if (arguments.length == 2) {
|
819
926
|
// entity(element,selector);
|
820
927
|
e = select(e, selector);
|
928
|
+
} else {
|
929
|
+
return null;
|
821
930
|
}
|
822
931
|
|
823
932
|
while (e) {
|
824
|
-
if (e.
|
825
|
-
return e.
|
933
|
+
if (e.__ENO_ENTITY) {
|
934
|
+
return e.__ENO_ENTITY;
|
826
935
|
} else {
|
827
936
|
e = e.parentElement;
|
828
937
|
}
|
@@ -831,32 +940,68 @@ function entity(e, selector) {
|
|
831
940
|
}
|
832
941
|
|
833
942
|
/**
|
834
|
-
*
|
835
|
-
* @param {Event} e
|
836
|
-
* @return {
|
943
|
+
* 根据事件或标签元素获取由eno.sets()对应标签元素
|
944
|
+
* @param {Event|HTMLElement} e 事件或标签元素
|
945
|
+
* @return {HTMLElement} 实体对象对应的标签元素
|
837
946
|
*/
|
838
947
|
function element(e) {
|
839
|
-
if (e
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
948
|
+
if (e) {
|
949
|
+
if (e.target) {
|
950
|
+
e = e.target;
|
951
|
+
} else
|
952
|
+
if (e.srcElement) {
|
953
|
+
e = e.srcElement;
|
954
|
+
} else {
|
955
|
+
e = select(e);
|
956
|
+
}
|
957
|
+
|
958
|
+
while (e) {
|
959
|
+
if (e.userData) {
|
960
|
+
return e;
|
961
|
+
} else {
|
962
|
+
e = e.parentElement;
|
963
|
+
}
|
964
|
+
}
|
844
965
|
}
|
966
|
+
return null;
|
967
|
+
}
|
845
968
|
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
969
|
+
function target(event, name, value) {
|
970
|
+
if (arguments.length == 1) {
|
971
|
+
// target(event);
|
972
|
+
return event.target || event.srcElement;
|
973
|
+
} else
|
974
|
+
if (arguments.length == 2) {
|
975
|
+
// target(event, name);
|
976
|
+
let element = event.target || event.srcElement;
|
977
|
+
while (element && element !== event.currentTarget) {
|
978
|
+
if (element.hasAttribute(name)) {
|
979
|
+
return element;
|
980
|
+
}
|
981
|
+
element = element.parentElement;
|
982
|
+
}
|
983
|
+
} else
|
984
|
+
if (arguments.length == 3) {
|
985
|
+
// target(event, name, value);
|
986
|
+
let element = event.target || event.srcElement;
|
987
|
+
while (element && element !== event.currentTarget) {
|
988
|
+
if (element.getAttribute(name) == value) {
|
989
|
+
return element;
|
990
|
+
}
|
991
|
+
element = element.parentElement;
|
851
992
|
}
|
852
993
|
}
|
853
994
|
return null;
|
854
995
|
}
|
855
996
|
|
856
997
|
/**
|
857
|
-
*
|
998
|
+
* 获取 URL 中的 Query String 指定名称的参数值或包含所有参数的实体对象
|
999
|
+
* @param {String} url URL
|
858
1000
|
* @param {String} name 参数名
|
859
1001
|
* @return {String} 参数值
|
1002
|
+
* @example eno.query(url);
|
1003
|
+
* @example eno.query(name);
|
1004
|
+
* @example eno.query(url,name);
|
860
1005
|
*/
|
861
1006
|
function query(url, name) {
|
862
1007
|
if (arguments.length == 0) {
|
@@ -888,10 +1033,13 @@ function query(url, name) {
|
|
888
1033
|
} else {
|
889
1034
|
return null;
|
890
1035
|
}
|
1036
|
+
} else {
|
1037
|
+
return null;
|
891
1038
|
}
|
892
1039
|
|
893
1040
|
if (url) {
|
894
1041
|
if (name) {
|
1042
|
+
// 查找指定参数值
|
895
1043
|
let start = url.indexOf(name);
|
896
1044
|
if (start >= 0) {
|
897
1045
|
start += name.length;
|
@@ -905,6 +1053,7 @@ function query(url, name) {
|
|
905
1053
|
}
|
906
1054
|
}
|
907
1055
|
} else {
|
1056
|
+
// 获取所有参数值
|
908
1057
|
// ?name1=value1&name2=value2
|
909
1058
|
let start = 1;
|
910
1059
|
let index = 1;
|
@@ -931,28 +1080,4 @@ function query(url, name) {
|
|
931
1080
|
}
|
932
1081
|
}
|
933
1082
|
return null;
|
934
|
-
}
|
935
|
-
|
936
|
-
/**
|
937
|
-
* 根据事件或元素获取属性指定的动作
|
938
|
-
* @param {Event} e
|
939
|
-
* @param {String} a
|
940
|
-
* @deprecated 1.1.3
|
941
|
-
*/
|
942
|
-
function action(e, a) {
|
943
|
-
if (e.target) {
|
944
|
-
e = e.target;
|
945
|
-
} else
|
946
|
-
if (e.srcElement) {
|
947
|
-
e = e.srcElement;
|
948
|
-
}
|
949
|
-
|
950
|
-
while (e) {
|
951
|
-
if (e.hasAttribute(a)) {
|
952
|
-
return true;
|
953
|
-
} else {
|
954
|
-
e = e.parentElement;
|
955
|
-
}
|
956
|
-
}
|
957
|
-
return false;
|
958
1083
|
}
|