clickgo 3.1.1-dev10 → 3.1.3-dev12
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/dist/app/demo/app.js +0 -72
- package/dist/app/demo/config.json +109 -0
- package/dist/app/demo/form/control/button/button.js +12 -11
- package/dist/app/demo/form/control/button/button.xml +6 -6
- package/dist/app/demo/form/control/check/check.js +14 -10
- package/dist/app/demo/form/control/file/file.js +15 -13
- package/dist/app/demo/form/control/{overflow/overflow.css → flow/flow.css} +0 -0
- package/dist/app/demo/form/control/flow/flow.js +64 -0
- package/dist/app/demo/form/control/{overflow/overflow.scss → flow/flow.scss} +0 -0
- package/dist/app/demo/form/control/flow/flow.xml +101 -0
- package/dist/app/demo/form/control/form/form.js +1 -1
- package/dist/app/demo/form/control/form/form.xml +3 -3
- package/dist/app/demo/form/control/img/img.xml +2 -2
- package/dist/app/demo/form/control/list/list.js +95 -75
- package/dist/app/demo/form/control/list/list.xml +15 -11
- package/dist/app/demo/form/control/marquee/marquee.js +12 -10
- package/dist/app/demo/form/control/menu/menu.js +10 -6
- package/dist/app/demo/form/control/monaco/monaco.js +50 -60
- package/dist/app/demo/form/control/monaco/monaco.xml +6 -5
- package/dist/app/demo/form/control/property/property.js +131 -127
- package/dist/app/demo/form/control/radio/radio.js +9 -5
- package/dist/app/demo/form/control/scroll/scroll.js +16 -12
- package/dist/app/demo/form/control/scroll/scroll.xml +10 -10
- package/dist/app/demo/form/control/select/select.js +132 -71
- package/dist/app/demo/form/control/select/select.xml +69 -67
- package/dist/app/demo/form/control/tab/tab.js +21 -20
- package/dist/app/demo/form/control/tab/tab.xml +2 -2
- package/dist/app/demo/form/control/text/text.js +53 -45
- package/dist/app/demo/form/control/text/text.xml +3 -3
- package/dist/app/demo/form/control/{greatview/greatview.css → vflow/vflow.css} +0 -0
- package/dist/app/demo/form/control/vflow/vflow.js +79 -0
- package/dist/app/demo/form/control/{greatview/greatview.scss → vflow/vflow.scss} +0 -0
- package/dist/app/demo/form/control/{greatview/greatview.xml → vflow/vflow.xml} +25 -25
- package/dist/app/demo/form/event/form/form.js +58 -56
- package/dist/app/demo/form/event/form/form.xml +3 -3
- package/dist/app/demo/form/event/screen/screen.js +30 -28
- package/dist/app/demo/form/event/screen/screen.xml +2 -2
- package/dist/app/demo/form/event/task/task.js +31 -31
- package/dist/app/demo/form/event/task/task.xml +3 -3
- package/dist/app/demo/form/main.js +166 -5
- package/dist/app/demo/form/main.xml +37 -35
- package/dist/app/demo/form/method/aform/aform.js +57 -0
- package/dist/app/demo/form/method/aform/aform.xml +35 -0
- package/dist/app/demo/form/method/aform/test.xml +6 -0
- package/dist/app/demo/form/method/core/core.js +11 -8
- package/dist/app/demo/form/method/core/core.xml +2 -1
- package/dist/app/demo/form/method/dom/dom.js +91 -99
- package/dist/app/demo/form/method/dom/dom.xml +6 -7
- package/dist/app/demo/form/method/form/form.js +10 -28
- package/dist/app/demo/form/method/form/form.xml +8 -15
- package/dist/app/demo/form/method/fs/fs.js +34 -33
- package/dist/app/demo/form/method/fs/fs.xml +1 -1
- package/dist/app/demo/form/method/fs/text.js +12 -12
- package/dist/app/demo/form/method/native/native.js +50 -0
- package/dist/app/demo/form/method/native/native.xml +12 -0
- package/dist/app/demo/form/method/system/system.js +50 -0
- package/dist/app/demo/form/method/system/system.xml +11 -0
- package/dist/app/demo/form/method/task/task.js +59 -61
- package/dist/app/demo/form/method/task/task.xml +4 -6
- package/dist/app/demo/form/method/theme/theme.js +14 -14
- package/dist/app/demo/form/method/tool/tool.js +29 -28
- package/dist/app/demo/form/method/tool/tool.xml +3 -3
- package/dist/app/demo/form/method/zip/zip.js +46 -41
- package/dist/app/demo/form/method/zip/zip.xml +1 -1
- package/dist/app/task/app.js +0 -25
- package/dist/app/task/config.json +29 -0
- package/dist/app/task/form/bar/bar.js +2 -2
- package/dist/app/task/form/bar/bar.xml +1 -1
- package/dist/clickgo.js +17 -5
- package/dist/clickgo.ts +22 -3
- package/dist/control/common.cgc +0 -0
- package/dist/control/form.cgc +0 -0
- package/dist/control/monaco.cgc +0 -0
- package/dist/control/property.cgc +0 -0
- package/dist/control/task.cgc +0 -0
- package/dist/global.css +1 -1
- package/dist/index.js +28 -8
- package/dist/index.ts +33 -7
- package/dist/lib/control.js +75 -105
- package/dist/lib/control.ts +102 -124
- package/dist/lib/core.js +108 -252
- package/dist/lib/core.ts +122 -268
- package/dist/lib/dom.js +564 -483
- package/dist/lib/dom.ts +703 -546
- package/dist/lib/form.js +170 -153
- package/dist/lib/form.ts +132 -99
- package/dist/lib/fs.js +1 -1
- package/dist/lib/fs.ts +1 -1
- package/dist/lib/native.js +135 -8
- package/dist/lib/native.ts +176 -12
- package/dist/lib/task.js +301 -175
- package/dist/lib/task.ts +330 -207
- package/dist/lib/tool.js +48 -1
- package/dist/lib/tool.ts +61 -0
- package/dist/lib/zip.ts +2 -0
- package/dist/theme/familiar.cgt +0 -0
- package/package.json +1 -1
- package/types/index.d.ts +26 -29
- package/dist/app/demo/form/control/greatview/greatview.js +0 -92
- package/dist/app/demo/form/control/overflow/overflow.js +0 -70
- package/dist/app/demo/form/control/overflow/overflow.xml +0 -98
- package/dist/app/demo/form/control/view/view.css +0 -1
- package/dist/app/demo/form/control/view/view.js +0 -73
- package/dist/app/demo/form/control/view/view.scss +0 -18
- package/dist/app/demo/form/control/view/view.xml +0 -94
- package/dist/app/demo/form/method/form/test.xml +0 -5
package/dist/lib/dom.ts
CHANGED
|
@@ -17,6 +17,7 @@ import * as types from '../../types';
|
|
|
17
17
|
import * as clickgo from '../clickgo';
|
|
18
18
|
import * as form from './form';
|
|
19
19
|
import * as core from './core';
|
|
20
|
+
import * as tool from './tool';
|
|
20
21
|
|
|
21
22
|
/** --- style list 的 div --- */
|
|
22
23
|
const topClass: string[] = ['#cg-form-list', '#cg-pop-list', '#cg-system', '#cg-simpletask', '#cg-launcher'];
|
|
@@ -31,17 +32,13 @@ function classUnfold(after?: string, out: string[] = []): string {
|
|
|
31
32
|
return arr.join(', ');
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
/*
|
|
35
|
-
#cg-gesture {box-sizing: border-box; position: fixed; z-index: 20020004; border: solid 3px #ff976a; border-radius: 50%; filter: drop-shadow(0 0 3px #ff976a); pointer-events: none; opacity: 0; transform: scale(0); width: 20px; height: 20px;}
|
|
36
|
-
#cg-gesture.done {background: #ff976a;}
|
|
37
|
-
*/
|
|
38
35
|
const styleList: HTMLDivElement = document.createElement('div');
|
|
39
36
|
styleList.style.display = 'none';
|
|
40
37
|
document.getElementsByTagName('body')[0].appendChild(styleList);
|
|
41
38
|
styleList.insertAdjacentHTML('beforeend', '<style id=\'cg-global-cursor\'></style>');
|
|
42
39
|
styleList.insertAdjacentHTML('beforeend', `<style id='cg-global'>
|
|
43
|
-
${classUnfold()} {-webkit-user-select: none; user-select: none;
|
|
44
|
-
${topClass.slice(0, 3).join(', ')} {left: 0; top: 0; width: 0; height: 0;}
|
|
40
|
+
${classUnfold()} {-webkit-user-select: none; user-select: none; cursor: default; box-sizing: border-box;}
|
|
41
|
+
${topClass.slice(0, 3).join(', ')} {left: 0; top: 0; width: 0; height: 0; position: absolute;}
|
|
45
42
|
${classUnfold('img')} {vertical-align: bottom;}
|
|
46
43
|
${classUnfold('::selection', ['#cg-launcher'])} {background-color: rgba(0, 0, 0, .1);}
|
|
47
44
|
${classUnfold('*')}, ${classUnfold('*::after')}, ${classUnfold('*::before')} {box-sizing: border-box; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); flex-shrink: 0;}
|
|
@@ -184,45 +181,41 @@ export function getStyleCount(taskId: number, type: 'theme' | 'control' | 'form'
|
|
|
184
181
|
return document.querySelectorAll(`#cg-style-task${taskId} > .cg-style-${type} > style`).length;
|
|
185
182
|
}
|
|
186
183
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
*/
|
|
191
|
-
export function getSize(el: HTMLElement): types.IDomSize {
|
|
192
|
-
const rect = el.getBoundingClientRect();
|
|
193
|
-
const cs = getComputedStyle(el);
|
|
194
|
-
const border = {
|
|
195
|
-
'top': parseFloat(cs.borderTopWidth),
|
|
196
|
-
'right': parseFloat(cs.borderRightWidth),
|
|
197
|
-
'bottom': parseFloat(cs.borderBottomWidth),
|
|
198
|
-
'left': parseFloat(cs.borderLeftWidth)
|
|
199
|
-
};
|
|
200
|
-
const padding = {
|
|
201
|
-
'top': parseFloat(cs.paddingTop),
|
|
202
|
-
'right': parseFloat(cs.paddingRight),
|
|
203
|
-
'bottom': parseFloat(cs.paddingBottom),
|
|
204
|
-
'left': parseFloat(cs.paddingLeft)
|
|
205
|
-
};
|
|
206
|
-
return {
|
|
207
|
-
'top': rect.top,
|
|
208
|
-
'right': rect.right,
|
|
209
|
-
'bottom': rect.bottom,
|
|
210
|
-
'left': rect.left,
|
|
211
|
-
'width': rect.width,
|
|
212
|
-
'height': rect.height,
|
|
213
|
-
'padding': padding,
|
|
214
|
-
'border': border,
|
|
215
|
-
'clientWidth': rect.width - border.left - border.right,
|
|
216
|
-
'clientHeight': rect.height - border.top - border.bottom,
|
|
217
|
-
'innerWidth': rect.width - border.left - border.right - padding.left - padding.right,
|
|
218
|
-
'innerHeight': rect.height - border.top - border.bottom - padding.top - padding.bottom,
|
|
219
|
-
'scrollWidth': el.scrollWidth,
|
|
220
|
-
'scrollHeight': el.scrollHeight
|
|
221
|
-
};
|
|
222
|
-
}
|
|
184
|
+
// -----------------
|
|
185
|
+
// --- watchSize ---
|
|
186
|
+
// -----------------
|
|
223
187
|
|
|
224
188
|
/** --- 被监视中的元素 --- */
|
|
225
|
-
const watchSizeList: types.IWatchSizeItem
|
|
189
|
+
const watchSizeList: Record<string, types.IWatchSizeItem> = {};
|
|
190
|
+
|
|
191
|
+
/** --- 监视元素的 data-cg-roindex --- */
|
|
192
|
+
let watchSizeIndex: number = 0;
|
|
193
|
+
|
|
194
|
+
// --- 创建 ro 对象 ---
|
|
195
|
+
const resizeObserver = new ResizeObserver(function(entries): void {
|
|
196
|
+
for (const entrie of entries) {
|
|
197
|
+
const el = entrie.target as HTMLElement;
|
|
198
|
+
if (!el.offsetParent) {
|
|
199
|
+
resizeObserver.unobserve(el);
|
|
200
|
+
if (watchSizeList[el.dataset.cgRoindex!]) {
|
|
201
|
+
delete watchSizeList[el.dataset.cgRoindex!];
|
|
202
|
+
}
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
const item = watchSizeList[el.dataset.cgRoindex!];
|
|
206
|
+
try {
|
|
207
|
+
const r = item.handler();
|
|
208
|
+
if (r instanceof Promise) {
|
|
209
|
+
r.catch(function(e) {
|
|
210
|
+
console.log('ResizeObserver', e);
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
catch (e) {
|
|
215
|
+
console.log('ResizeObserver', e);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
});
|
|
226
219
|
|
|
227
220
|
/**
|
|
228
221
|
* --- 添加监视 Element 对象大小,元素移除后自动停止监视(浏览器原生效果) ---
|
|
@@ -233,108 +226,89 @@ const watchSizeList: types.IWatchSizeItem[] = [];
|
|
|
233
226
|
*/
|
|
234
227
|
export function watchSize(
|
|
235
228
|
el: HTMLElement,
|
|
236
|
-
cb: (
|
|
229
|
+
cb: () => void | Promise<void>,
|
|
237
230
|
immediate: boolean = false,
|
|
238
231
|
taskId?: number
|
|
239
|
-
):
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
if (item.el === el) {
|
|
243
|
-
return fsize;
|
|
244
|
-
}
|
|
232
|
+
): boolean {
|
|
233
|
+
if (isWatchSize(el)) {
|
|
234
|
+
return false;
|
|
245
235
|
}
|
|
246
236
|
if (immediate) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
r
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
const resizeObserver = new (window as any).ResizeObserver(function(): void {
|
|
255
|
-
const size = getSize(el);
|
|
256
|
-
if (Number.isNaN(size.clientWidth)) {
|
|
257
|
-
return;
|
|
237
|
+
try {
|
|
238
|
+
const r = cb();
|
|
239
|
+
if (r instanceof Promise) {
|
|
240
|
+
r.catch(function(e) {
|
|
241
|
+
console.log('dom.watchSize', e);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
258
244
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
r.catch(function(e) {
|
|
262
|
-
console.log(e);
|
|
263
|
-
});
|
|
245
|
+
catch (e) {
|
|
246
|
+
console.log('dom.watchSize', e);
|
|
264
247
|
}
|
|
265
|
-
}
|
|
248
|
+
}
|
|
266
249
|
resizeObserver.observe(el);
|
|
267
|
-
watchSizeList
|
|
250
|
+
watchSizeList[watchSizeIndex] = {
|
|
268
251
|
'el': el,
|
|
269
|
-
'
|
|
252
|
+
'handler': cb,
|
|
270
253
|
'taskId': taskId
|
|
271
|
-
}
|
|
272
|
-
|
|
254
|
+
};
|
|
255
|
+
el.dataset.cgRoindex = watchSizeIndex.toString();
|
|
256
|
+
++watchSizeIndex;
|
|
257
|
+
return true;
|
|
273
258
|
}
|
|
274
259
|
|
|
275
260
|
/**
|
|
276
|
-
* --- 移除监视 Element 对象大小
|
|
261
|
+
* --- 移除监视 Element 对象大小 ---
|
|
277
262
|
* @param el 要移除监视
|
|
278
263
|
* @param taskId 校验任务 id,App 模式下无效
|
|
279
264
|
*/
|
|
280
265
|
export function unwatchSize(el: HTMLElement, taskId?: number): void {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
if (item.el !== el) {
|
|
284
|
-
continue;
|
|
285
|
-
}
|
|
286
|
-
if (taskId && taskId !== item.taskId) {
|
|
287
|
-
// --- taskId 校验失败 ---
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
// --- 要移除 ---
|
|
291
|
-
if (item.el.offsetParent) {
|
|
292
|
-
item.ro.unobserve(item.el);
|
|
293
|
-
}
|
|
294
|
-
watchSizeList.splice(i, 1);
|
|
295
|
-
--i;
|
|
266
|
+
const index = el.dataset.cgRoindex;
|
|
267
|
+
if (index === undefined) {
|
|
296
268
|
return;
|
|
297
269
|
}
|
|
270
|
+
const item = watchSizeList[index];
|
|
271
|
+
if (taskId && item.taskId !== taskId) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
resizeObserver.unobserve(el);
|
|
275
|
+
el.removeAttribute('data-cg-roindex');
|
|
276
|
+
delete watchSizeList[index];
|
|
298
277
|
}
|
|
299
278
|
|
|
300
279
|
/**
|
|
301
|
-
* ---
|
|
302
|
-
* @param
|
|
280
|
+
* --- 检测一个标签是否正在被 watchSize ---
|
|
281
|
+
* @param el 要检测的标签
|
|
303
282
|
*/
|
|
304
|
-
export function
|
|
305
|
-
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
for (let i = 0; i < watchSizeList.length; ++i) {
|
|
309
|
-
const item = watchSizeList[i];
|
|
310
|
-
if (taskId !== item.taskId) {
|
|
311
|
-
continue;
|
|
312
|
-
}
|
|
313
|
-
if (item.el.offsetParent) {
|
|
314
|
-
item.ro.unobserve(item.el);
|
|
315
|
-
}
|
|
316
|
-
watchSizeList.splice(i, 1);
|
|
317
|
-
--i;
|
|
318
|
-
}
|
|
283
|
+
export function isWatchSize(el: HTMLElement): boolean {
|
|
284
|
+
return el.dataset.cgRoindex ? true : false;
|
|
319
285
|
}
|
|
320
286
|
|
|
321
287
|
/**
|
|
322
|
-
* ---
|
|
288
|
+
* --- 清除某个任务的所有 watch size 监视,App 模式下无效 ---
|
|
289
|
+
* @param taskId 任务 id
|
|
323
290
|
*/
|
|
324
|
-
function
|
|
325
|
-
for (
|
|
326
|
-
const item = watchSizeList[
|
|
327
|
-
if (item.
|
|
291
|
+
export function clearWatchSize(taskId: number): void {
|
|
292
|
+
for (const index in watchSizeList) {
|
|
293
|
+
const item = watchSizeList[index];
|
|
294
|
+
if (taskId !== item.taskId) {
|
|
328
295
|
continue;
|
|
329
296
|
}
|
|
330
|
-
|
|
331
|
-
|
|
297
|
+
resizeObserver.unobserve(item.el);
|
|
298
|
+
item.el.removeAttribute('data-cg-roindex');
|
|
299
|
+
delete watchSizeList[index];
|
|
332
300
|
}
|
|
333
301
|
}
|
|
334
|
-
|
|
302
|
+
|
|
303
|
+
// -------------
|
|
304
|
+
// --- watch ---
|
|
305
|
+
// -------------
|
|
335
306
|
|
|
336
307
|
/** --- 监视 dom 变动中的元素 */
|
|
337
|
-
const watchList: types.IWatchItem
|
|
308
|
+
const watchList: Record<string, types.IWatchItem> = {};
|
|
309
|
+
|
|
310
|
+
/** --- 监视元素的 data-cg-moindex --- */
|
|
311
|
+
let watchIndex: number = 0;
|
|
338
312
|
|
|
339
313
|
/**
|
|
340
314
|
* --- 添加 DOM 内容变化监视 ---
|
|
@@ -343,10 +317,24 @@ const watchList: types.IWatchItem[] = [];
|
|
|
343
317
|
* @param mode 监听模式
|
|
344
318
|
* @param taskId 归属到一个任务里可留空,App 模式下无效
|
|
345
319
|
*/
|
|
346
|
-
export function watch(el: HTMLElement, cb: () => void
|
|
320
|
+
export function watch(el: HTMLElement, cb: (mutations: MutationRecord[]) => void | Promise<void>, mode: 'child' | 'childsub' | 'style' | 'default' = 'default', immediate: boolean = false, taskId?: number): boolean {
|
|
321
|
+
if (isWatch(el)) {
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
347
324
|
if (immediate) {
|
|
348
|
-
|
|
325
|
+
try {
|
|
326
|
+
const r = cb([]);
|
|
327
|
+
if (r instanceof Promise) {
|
|
328
|
+
r.catch(function(e) {
|
|
329
|
+
console.log('dom.watch', e);
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
catch (e) {
|
|
334
|
+
console.log('dom.watch', e);
|
|
335
|
+
}
|
|
349
336
|
}
|
|
337
|
+
const index = watchIndex;
|
|
350
338
|
let moi: MutationObserverInit;
|
|
351
339
|
switch (mode) {
|
|
352
340
|
case 'child': {
|
|
@@ -385,13 +373,35 @@ export function watch(el: HTMLElement, cb: () => void, mode: 'child' | 'childsub
|
|
|
385
373
|
moi = mode;
|
|
386
374
|
}
|
|
387
375
|
}
|
|
388
|
-
const mo = new MutationObserver(
|
|
376
|
+
const mo = new MutationObserver((mutations) => {
|
|
377
|
+
if (!el.offsetParent) {
|
|
378
|
+
mo.disconnect();
|
|
379
|
+
if (watchList[index]) {
|
|
380
|
+
delete watchList[index];
|
|
381
|
+
}
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
try {
|
|
385
|
+
const r = cb(mutations);
|
|
386
|
+
if (r instanceof Promise) {
|
|
387
|
+
r.catch(function(e) {
|
|
388
|
+
console.log('dom.watch', e);
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
catch (e) {
|
|
393
|
+
console.log('dom.watch', e);
|
|
394
|
+
}
|
|
395
|
+
});
|
|
389
396
|
mo.observe(el, moi);
|
|
390
|
-
watchList
|
|
397
|
+
watchList[index] = {
|
|
391
398
|
'el': el,
|
|
392
399
|
'mo': mo,
|
|
393
400
|
'taskId': taskId
|
|
394
|
-
}
|
|
401
|
+
};
|
|
402
|
+
el.dataset.cgMoindex = index.toString();
|
|
403
|
+
++watchIndex;
|
|
404
|
+
return true;
|
|
395
405
|
/*
|
|
396
406
|
{
|
|
397
407
|
'attributeFilter': ['style', 'class'],
|
|
@@ -404,92 +414,97 @@ export function watch(el: HTMLElement, cb: () => void, mode: 'child' | 'childsub
|
|
|
404
414
|
}
|
|
405
415
|
|
|
406
416
|
/**
|
|
407
|
-
* --- 移除监视 Element
|
|
417
|
+
* --- 移除监视 Element 对象变动 ---
|
|
408
418
|
* @param el 要移除监视
|
|
409
419
|
* @param taskId 校验任务 id 可留空,App 模式下无效
|
|
410
420
|
*/
|
|
411
421
|
export function unwatch(el: HTMLElement, taskId?: number): void {
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
// --- taskId 校验失败 ---
|
|
419
|
-
return;
|
|
420
|
-
}
|
|
421
|
-
// --- 要移除 ---
|
|
422
|
-
if (item.el.offsetParent) {
|
|
423
|
-
item.mo.disconnect();
|
|
424
|
-
}
|
|
425
|
-
watchList.splice(i, 1);
|
|
426
|
-
--i;
|
|
422
|
+
const index = el.dataset.cgMoindex;
|
|
423
|
+
if (index === undefined) {
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
const item = watchList[index];
|
|
427
|
+
if (taskId && item.taskId !== taskId) {
|
|
427
428
|
return;
|
|
428
429
|
}
|
|
430
|
+
el.removeAttribute('data-cg-moindex');
|
|
431
|
+
watchList[index].mo.disconnect();
|
|
432
|
+
delete watchList[index];
|
|
429
433
|
}
|
|
430
434
|
|
|
431
435
|
/**
|
|
432
|
-
* ---
|
|
433
|
-
* @param
|
|
436
|
+
* --- 检测一个标签是否正在被 watchSize ---
|
|
437
|
+
* @param el 要检测的标签
|
|
434
438
|
*/
|
|
435
|
-
export function
|
|
436
|
-
|
|
437
|
-
return;
|
|
438
|
-
}
|
|
439
|
-
for (let i = 0; i < watchList.length; ++i) {
|
|
440
|
-
const item = watchList[i];
|
|
441
|
-
if (taskId !== item.taskId) {
|
|
442
|
-
continue;
|
|
443
|
-
}
|
|
444
|
-
if (item.el.offsetParent) {
|
|
445
|
-
item.mo.disconnect();
|
|
446
|
-
}
|
|
447
|
-
watchList.splice(i, 1);
|
|
448
|
-
--i;
|
|
449
|
-
}
|
|
439
|
+
export function isWatch(el: HTMLElement): boolean {
|
|
440
|
+
return el.dataset.cgMoindex ? true : false;
|
|
450
441
|
}
|
|
451
442
|
|
|
452
443
|
/**
|
|
453
|
-
* ---
|
|
444
|
+
* --- 清除某个任务下面的所有 watch 监视,App 模式下无效 ---
|
|
445
|
+
* @param taskId 任务 id,App 模式下无效
|
|
454
446
|
*/
|
|
455
|
-
function
|
|
456
|
-
for (
|
|
457
|
-
const item = watchList[
|
|
458
|
-
if (item.
|
|
447
|
+
export function clearWatch(taskId: number): void {
|
|
448
|
+
for (const index in watchList) {
|
|
449
|
+
const item = watchList[index];
|
|
450
|
+
if (taskId !== item.taskId) {
|
|
459
451
|
continue;
|
|
460
452
|
}
|
|
461
|
-
|
|
462
|
-
|
|
453
|
+
item.el.removeAttribute('data-cg-moindex');
|
|
454
|
+
item.mo.disconnect();
|
|
455
|
+
delete watchList[index];
|
|
463
456
|
}
|
|
464
457
|
}
|
|
465
|
-
setInterval(cgClearWatch, 1000 * 60 * 5);
|
|
466
458
|
|
|
467
|
-
|
|
459
|
+
// ------------------
|
|
460
|
+
// --- watchStyle ---
|
|
461
|
+
// ------------------
|
|
462
|
+
|
|
463
|
+
const watchStyleList: Record<string, Record<string, {
|
|
468
464
|
'el': HTMLElement;
|
|
469
465
|
'sd': CSSStyleDeclaration;
|
|
470
466
|
'names': Record<string, {
|
|
471
|
-
'
|
|
472
|
-
'cb': Array<(name: string, value: string) => void>;
|
|
467
|
+
'val': string;
|
|
468
|
+
'cb': Array<(name: string, value: string, old: string) => void>;
|
|
473
469
|
}>;
|
|
474
|
-
}
|
|
470
|
+
}>> = {};
|
|
471
|
+
|
|
472
|
+
/** --- 监视元素的 data-cg-styleindex --- */
|
|
473
|
+
let watchStyleIndex: number = 0;
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* --- 监听一个标签的计算后样式的变化 ---
|
|
477
|
+
* @param el 对象
|
|
478
|
+
* @param name 样式名
|
|
479
|
+
* @param cb 变更回调
|
|
480
|
+
* @param immediate 是否立刻执行一次
|
|
481
|
+
*/
|
|
475
482
|
export function watchStyle(
|
|
476
483
|
el: HTMLElement,
|
|
477
484
|
name: string | string[],
|
|
478
|
-
cb: (name: string, value: string) => void,
|
|
485
|
+
cb: (name: string, value: string, old: string) => void,
|
|
479
486
|
immediate: boolean = false
|
|
480
487
|
): void {
|
|
481
488
|
if (typeof name === 'string') {
|
|
482
489
|
name = [name];
|
|
483
490
|
}
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
491
|
+
// --- 获取监视标签的所属 wrap ---
|
|
492
|
+
const formWrap = findParentByData(el, 'form-id');
|
|
493
|
+
if (!formWrap) {
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
const formId = formWrap.dataset.formId!;
|
|
497
|
+
if (!watchStyleList[formId]) {
|
|
498
|
+
watchStyleList[formId] = {};
|
|
499
|
+
}
|
|
500
|
+
const index = el.dataset.cgStyleindex;
|
|
501
|
+
if (index) {
|
|
502
|
+
const item = watchStyleList[formId][index];
|
|
488
503
|
// --- 已经有监听了 ---
|
|
489
504
|
for (const n of name) {
|
|
490
505
|
if (!item.names[n]) {
|
|
491
506
|
item.names[n] = {
|
|
492
|
-
'
|
|
507
|
+
'val': (item.sd as any)[n],
|
|
493
508
|
'cb': [cb]
|
|
494
509
|
};
|
|
495
510
|
}
|
|
@@ -497,69 +512,251 @@ export function watchStyle(
|
|
|
497
512
|
item.names[n].cb.push(cb);
|
|
498
513
|
}
|
|
499
514
|
if (immediate) {
|
|
500
|
-
cb(n, (item.sd as any)[n]);
|
|
515
|
+
cb(n, (item.sd as any)[n], '');
|
|
501
516
|
}
|
|
502
517
|
}
|
|
503
518
|
return;
|
|
504
519
|
}
|
|
505
520
|
// --- 创建监听 ---
|
|
506
521
|
const sd = getComputedStyle(el);
|
|
507
|
-
|
|
522
|
+
watchStyleList[formId][watchStyleIndex] = {
|
|
508
523
|
'el': el,
|
|
509
524
|
'sd': sd,
|
|
510
525
|
'names': {}
|
|
511
|
-
}
|
|
512
|
-
const item =
|
|
526
|
+
};
|
|
527
|
+
const item = watchStyleList[formId][watchStyleIndex];
|
|
513
528
|
for (const n of name) {
|
|
514
529
|
item.names[n] = {
|
|
515
|
-
'
|
|
530
|
+
'val': (item.sd as any)[n],
|
|
516
531
|
'cb': [cb]
|
|
517
532
|
};
|
|
518
533
|
if (immediate) {
|
|
519
|
-
cb(n, (item.sd as any)[n]);
|
|
534
|
+
cb(n, (item.sd as any)[n], '');
|
|
520
535
|
}
|
|
521
536
|
}
|
|
537
|
+
el.dataset.cgStyleindex = watchStyleIndex.toString();
|
|
538
|
+
++watchStyleIndex;
|
|
522
539
|
}
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
540
|
+
|
|
541
|
+
/** --- watch style 的 timer --- */
|
|
542
|
+
let watchStyleTimer = 0;
|
|
543
|
+
const watchStyleHandler = function(): void {
|
|
544
|
+
// --- 为什么要判断 form.getFocus 存在否,因为 form 类可能还没加载出来,这个函数就已经开始执行了 ---
|
|
545
|
+
if (form.getFocus) {
|
|
546
|
+
// --- 只判断和执行活跃中的窗体的监听事件 ---
|
|
547
|
+
const formId: number | null = form.getFocus();
|
|
548
|
+
if (formId && watchStyleList[formId]) {
|
|
549
|
+
for (const index in watchStyleList[formId]) {
|
|
550
|
+
const item = watchStyleList[formId][index];
|
|
551
|
+
if (!item.el.offsetParent) {
|
|
552
|
+
delete watchStyleList[formId][index];
|
|
553
|
+
if (!Object.keys(watchStyleList[formId]).length) {
|
|
554
|
+
delete watchStyleList[formId];
|
|
555
|
+
}
|
|
556
|
+
continue;
|
|
557
|
+
}
|
|
558
|
+
// --- 执行 cb ---
|
|
559
|
+
for (const name in item.names) {
|
|
560
|
+
if ((item.sd as any)[name] === item.names[name].val) {
|
|
561
|
+
continue;
|
|
562
|
+
}
|
|
563
|
+
const old = item.names[name].val;
|
|
564
|
+
item.names[name].val = (item.sd as any)[name];
|
|
565
|
+
for (const cb of item.names[name].cb) {
|
|
566
|
+
cb(name, (item.sd as any)[name], old);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
539
569
|
}
|
|
540
570
|
}
|
|
541
571
|
}
|
|
542
|
-
requestAnimationFrame(
|
|
572
|
+
watchStyleTimer = requestAnimationFrame(watchStyleHandler);
|
|
543
573
|
};
|
|
544
|
-
|
|
574
|
+
watchStyleHandler();
|
|
545
575
|
|
|
546
576
|
/**
|
|
547
577
|
* --- 检测一个标签是否正在被 watchStyle ---
|
|
548
578
|
* @param el 要检测的标签
|
|
549
579
|
*/
|
|
550
580
|
export function isWatchStyle(el: HTMLElement): boolean {
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
581
|
+
return el.dataset.cgStyleindex ? true : false;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* --- 清除某个窗体的所有 watch style 监视,App 模式下无效 ---
|
|
586
|
+
* @param formId 窗体 id
|
|
587
|
+
*/
|
|
588
|
+
export function clearWatchStyle(formId: number | string): void {
|
|
589
|
+
if (!watchStyleList[formId]) {
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
for (const index in watchStyleList[formId]) {
|
|
593
|
+
const item = watchStyleList[formId][index];
|
|
594
|
+
item.el.removeAttribute('data-cg-styleindex');
|
|
595
|
+
}
|
|
596
|
+
delete watchStyleList[formId];
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
// ---------------------
|
|
600
|
+
// --- watchProperty ---
|
|
601
|
+
// ---------------------
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* --- 监听中的标签对象,对应 formId -> 数组列表 ---
|
|
605
|
+
*/
|
|
606
|
+
const watchPropertyObjects: Record<string, Record<string, {
|
|
607
|
+
'el': HTMLElement;
|
|
608
|
+
'names': Record<string, {
|
|
609
|
+
'val': string;
|
|
610
|
+
'cb': Array<(name: string, value: string) => void>;
|
|
611
|
+
}>;
|
|
612
|
+
}>> = {};
|
|
613
|
+
|
|
614
|
+
/** --- 监视元素的 data-cg-propertyindex --- */
|
|
615
|
+
let watchPropertyIndex: number = 0;
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* --- 监听一个对象的属性变化 ---
|
|
619
|
+
* @param el 对象
|
|
620
|
+
* @param name 属性名
|
|
621
|
+
* @param cb 回调函数
|
|
622
|
+
* @param immediate 是否立即执行一次
|
|
623
|
+
*/
|
|
624
|
+
export function watchProperty(
|
|
625
|
+
el: HTMLElement,
|
|
626
|
+
name: string | string[],
|
|
627
|
+
cb: (name: string, value: string) => void,
|
|
628
|
+
immediate: boolean = false
|
|
629
|
+
): void {
|
|
630
|
+
if (typeof name === 'string') {
|
|
631
|
+
name = [name];
|
|
632
|
+
}
|
|
633
|
+
// --- 获取监视标签的所属 wrap ---
|
|
634
|
+
const formWrap = findParentByData(el, 'form-id');
|
|
635
|
+
if (!formWrap) {
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
const formId = formWrap.dataset.formId!;
|
|
639
|
+
if (!watchPropertyObjects[formId]) {
|
|
640
|
+
watchPropertyObjects[formId] = {};
|
|
641
|
+
}
|
|
642
|
+
const index = el.dataset.cgPropertyindex;
|
|
643
|
+
if (index) {
|
|
644
|
+
const item = watchPropertyObjects[formId][index];
|
|
645
|
+
// --- 已经有监听了 ---
|
|
646
|
+
for (const n of name) {
|
|
647
|
+
if (!item.names[n]) {
|
|
648
|
+
item.names[n] = {
|
|
649
|
+
'val': (item.el as any)[n],
|
|
650
|
+
'cb': [cb]
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
else {
|
|
654
|
+
item.names[n].cb.push(cb);
|
|
655
|
+
}
|
|
656
|
+
if (immediate) {
|
|
657
|
+
cb(n, (item.el as any)[n]);
|
|
658
|
+
}
|
|
554
659
|
}
|
|
555
|
-
return
|
|
660
|
+
return;
|
|
556
661
|
}
|
|
557
|
-
|
|
662
|
+
// --- 创建监听 ---
|
|
663
|
+
watchPropertyObjects[formId][watchPropertyIndex] = {
|
|
664
|
+
'el': el,
|
|
665
|
+
'names': {}
|
|
666
|
+
};
|
|
667
|
+
const item = watchPropertyObjects[formId][watchPropertyIndex];
|
|
668
|
+
for (const n of name) {
|
|
669
|
+
item.names[n] = {
|
|
670
|
+
'val': (item.el as any)[n],
|
|
671
|
+
'cb': [cb]
|
|
672
|
+
};
|
|
673
|
+
if (immediate) {
|
|
674
|
+
cb(n, (item.el as any)[n]);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
el.dataset.cgPropertyindex = watchPropertyIndex.toString();
|
|
678
|
+
++watchPropertyIndex;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/** --- watch property 的 timer --- */
|
|
682
|
+
let watchPropertyTimer = 0;
|
|
683
|
+
const watchPropertyHandler = function(): void {
|
|
684
|
+
// --- 为什么要判断 form.getFocus 存在否,因为 form 类可能还没加载出来,这个函数就已经开始执行了 ---
|
|
685
|
+
if (form.getFocus) {
|
|
686
|
+
// --- 只判断和执行活跃中的窗体的监听事件 ---
|
|
687
|
+
const formId: number | null = form.getFocus();
|
|
688
|
+
if (formId && watchPropertyObjects[formId]) {
|
|
689
|
+
for (const index in watchPropertyObjects[formId]) {
|
|
690
|
+
const item = watchPropertyObjects[formId][index];
|
|
691
|
+
if (!item.el.offsetParent) {
|
|
692
|
+
delete watchPropertyObjects[formId][index];
|
|
693
|
+
if (!Object.keys(watchPropertyObjects[formId]).length) {
|
|
694
|
+
delete watchPropertyObjects[formId];
|
|
695
|
+
}
|
|
696
|
+
continue;
|
|
697
|
+
}
|
|
698
|
+
// --- 执行 cb ---
|
|
699
|
+
for (const name in item.names) {
|
|
700
|
+
if ((item.el as any)[name] === item.names[name].val) {
|
|
701
|
+
continue;
|
|
702
|
+
}
|
|
703
|
+
item.names[name].val = (item.el as any)[name];
|
|
704
|
+
for (const cb of item.names[name].cb) {
|
|
705
|
+
cb(name, (item.el as any)[name]);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
watchPropertyTimer = requestAnimationFrame(watchPropertyHandler);
|
|
712
|
+
};
|
|
713
|
+
watchPropertyHandler();
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* --- 检测一个标签是否正在被 watchProperty ---
|
|
717
|
+
* @param el 要检测的标签
|
|
718
|
+
*/
|
|
719
|
+
export function isWatchProperty(el: HTMLElement): boolean {
|
|
720
|
+
return el.dataset.cgPropertyindex ? true : false;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* --- 清除某个窗体的所有 watch property 监视,虽然窗体结束后相关监视永远不会再被执行,但是会形成冗余,App 模式下无效 ---
|
|
725
|
+
* @param formId 窗体 id
|
|
726
|
+
*/
|
|
727
|
+
export function clearWatchProperty(formId: number | string): void {
|
|
728
|
+
if (!watchPropertyObjects[formId]) {
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
for (const index in watchPropertyObjects[formId]) {
|
|
732
|
+
const item = watchPropertyObjects[formId][index];
|
|
733
|
+
item.el.removeAttribute('data-cg-propertyindex');
|
|
734
|
+
}
|
|
735
|
+
delete watchPropertyObjects[formId];
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
/**
|
|
739
|
+
* --- 鼠标/手指没移动时,click 才生效 ---
|
|
740
|
+
* @param e 事件对象
|
|
741
|
+
* @param handler 回调
|
|
742
|
+
*/
|
|
743
|
+
export function bindClick(e: MouseEvent | TouchEvent, handler: () => void): void {
|
|
744
|
+
const x = e instanceof MouseEvent ? e.clientX : e.touches[0].clientX;
|
|
745
|
+
const y = e instanceof MouseEvent ? e.clientY : e.touches[0].clientY;
|
|
746
|
+
bindDown(e, {
|
|
747
|
+
up: (ne) => {
|
|
748
|
+
const nx = ne instanceof MouseEvent ? ne.clientX : ne.touches[0].clientX;
|
|
749
|
+
const ny = ne instanceof MouseEvent ? ne.clientY : ne.touches[0].clientY;
|
|
750
|
+
if (nx === x && ny === y) {
|
|
751
|
+
handler();
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
});
|
|
558
755
|
}
|
|
559
756
|
|
|
560
757
|
/**
|
|
561
|
-
* ---
|
|
562
|
-
* @param
|
|
758
|
+
* --- 绑定按下以及弹起事件,touch 和 mouse 只会绑定一个 ---
|
|
759
|
+
* @param oe MouseEvent | TouchEvent
|
|
563
760
|
* @param opt 回调选项
|
|
564
761
|
*/
|
|
565
762
|
export function bindDown(oe: MouseEvent | TouchEvent, opt: types.IBindDownOptions): void {
|
|
@@ -583,7 +780,7 @@ export function bindDown(oe: MouseEvent | TouchEvent, opt: types.IBindDownOption
|
|
|
583
780
|
let end: ((e: MouseEvent | TouchEvent) => void) | undefined = undefined;
|
|
584
781
|
const move = function(e: MouseEvent | TouchEvent): void {
|
|
585
782
|
// --- 虽然上层已经有 preventDefault 了,但是有可能 e.target 会被注销,这样就响应不到上层的 preventDefault 事件,所以要在这里再加一个 ---
|
|
586
|
-
if (!e.target || !(e.target as HTMLElement).offsetParent) {
|
|
783
|
+
if ((!e.target || !(e.target as HTMLElement).offsetParent) && e.cancelable) {
|
|
587
784
|
e.preventDefault();
|
|
588
785
|
}
|
|
589
786
|
/** --- 本次的移动方向 --- */
|
|
@@ -683,380 +880,314 @@ export function bindDown(oe: MouseEvent | TouchEvent, opt: types.IBindDownOption
|
|
|
683
880
|
opt.down?.(oe);
|
|
684
881
|
}
|
|
685
882
|
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
'
|
|
690
|
-
|
|
691
|
-
'
|
|
692
|
-
|
|
693
|
-
'
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
'
|
|
700
|
-
'xy': 0,
|
|
701
|
-
'tx': 0, // 最终 x
|
|
702
|
-
'ty': 0,
|
|
703
|
-
'dir': null,
|
|
704
|
-
'timers': {
|
|
705
|
-
'ani': 0,
|
|
706
|
-
'sleep': 0
|
|
707
|
-
}
|
|
883
|
+
/** --- 绑定拖拉响应操作的 wheel 数据对象 --- */
|
|
884
|
+
const gestureWheel = {
|
|
885
|
+
/** --- 最后一次响应事件时间 --- */
|
|
886
|
+
'last': 0,
|
|
887
|
+
/** --- 本轮 offset 滚动距离 --- */
|
|
888
|
+
'offset': 0,
|
|
889
|
+
/** --- 本轮是否已经完成了滚动 --- */
|
|
890
|
+
'done': false,
|
|
891
|
+
/** --- 未执行等待隐藏的 timer --- */
|
|
892
|
+
'timer': 0,
|
|
893
|
+
/** --- 是否等待首次执行中 --- */
|
|
894
|
+
'firstTimer': false,
|
|
895
|
+
/** --- 本轮滚动的方向 --- */
|
|
896
|
+
'dir': ''
|
|
708
897
|
};
|
|
709
898
|
|
|
710
|
-
function clearGestureData(): void {
|
|
711
|
-
bindGestureData.xx = 0;
|
|
712
|
-
bindGestureData.xy = 0;
|
|
713
|
-
bindGestureData.tx = 0;
|
|
714
|
-
bindGestureData.ty = 0;
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
function bindGestureAnimation(opt: { 'rect': DOMRect; 'dirs'?: Array<('top' | 'right' | 'bottom' | 'left')>; handler: (dir: 'top' | 'right' | 'bottom' | 'left') => void; }): void {
|
|
718
|
-
if (!bindGestureData.el) {
|
|
719
|
-
return;
|
|
720
|
-
}
|
|
721
|
-
const speed: number = 6;
|
|
722
|
-
const gestureElement = document.getElementById('cg-gesture')!;
|
|
723
|
-
const dirs = opt.dirs ?? ['top', 'bottom'];
|
|
724
|
-
|
|
725
|
-
if (bindGestureData.tx > bindGestureData.xx) {
|
|
726
|
-
bindGestureData.xx += speed;
|
|
727
|
-
if (bindGestureData.xx > bindGestureData.tx) {
|
|
728
|
-
bindGestureData.xx = bindGestureData.tx;
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
else {
|
|
732
|
-
bindGestureData.xx -= speed;
|
|
733
|
-
if (bindGestureData.xx < bindGestureData.tx) {
|
|
734
|
-
bindGestureData.xx = bindGestureData.tx;
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
if (bindGestureData.ty > bindGestureData.xy) {
|
|
738
|
-
bindGestureData.xy += speed;
|
|
739
|
-
if (bindGestureData.xy > bindGestureData.ty) {
|
|
740
|
-
bindGestureData.xy = bindGestureData.ty;
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
else {
|
|
744
|
-
bindGestureData.xy -= speed;
|
|
745
|
-
if (bindGestureData.xy < bindGestureData.ty) {
|
|
746
|
-
bindGestureData.xy = bindGestureData.ty;
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
const xxAbs = Math.abs(bindGestureData.xx);
|
|
750
|
-
const xyAbs = Math.abs(bindGestureData.xy);
|
|
751
|
-
if ((!dirs.includes('top') && !dirs.includes('bottom')) || ((xxAbs > xyAbs) && (dirs.includes('left') || dirs.includes('right')))) {
|
|
752
|
-
// --- 水平 ---
|
|
753
|
-
if (bindGestureData.xx < 0) {
|
|
754
|
-
// --- left ---
|
|
755
|
-
if (!dirs.includes('left')) {
|
|
756
|
-
gestureElement.style.opacity = '0';
|
|
757
|
-
clearGestureData();
|
|
758
|
-
return;
|
|
759
|
-
}
|
|
760
|
-
gestureElement.style.opacity = '1';
|
|
761
|
-
if (xxAbs === 90) {
|
|
762
|
-
bindGestureData.dir = 'left';
|
|
763
|
-
gestureElement.classList.add('done');
|
|
764
|
-
}
|
|
765
|
-
else {
|
|
766
|
-
bindGestureData.dir = null;
|
|
767
|
-
gestureElement.classList.remove('done');
|
|
768
|
-
}
|
|
769
|
-
gestureElement.style.top = (opt.rect.top + ((opt.rect.height - 20) / 2)).toString() + 'px';
|
|
770
|
-
gestureElement.style.left = (opt.rect.left - 10 + (xxAbs / 1.5)).toString() + 'px';
|
|
771
|
-
gestureElement.style.transform = 'scale(' + (xxAbs / 90).toString() + ')';
|
|
772
|
-
}
|
|
773
|
-
else {
|
|
774
|
-
// --- right ---
|
|
775
|
-
if (!dirs.includes('right')) {
|
|
776
|
-
gestureElement.style.opacity = '0';
|
|
777
|
-
clearGestureData();
|
|
778
|
-
return;
|
|
779
|
-
}
|
|
780
|
-
gestureElement.style.opacity = '1';
|
|
781
|
-
if (xxAbs === 90) {
|
|
782
|
-
bindGestureData.dir = 'right';
|
|
783
|
-
gestureElement.classList.add('done');
|
|
784
|
-
}
|
|
785
|
-
else {
|
|
786
|
-
bindGestureData.dir = null;
|
|
787
|
-
gestureElement.classList.remove('done');
|
|
788
|
-
}
|
|
789
|
-
gestureElement.style.top = (opt.rect.top + ((opt.rect.height - 20) / 2)).toString() + 'px';
|
|
790
|
-
gestureElement.style.left = (opt.rect.left + opt.rect.width - 10 - (xxAbs / 1.5)).toString() + 'px';
|
|
791
|
-
gestureElement.style.transform = 'scale(' + (xxAbs / 90).toString() + ')';
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
else {
|
|
795
|
-
if (bindGestureData.xy < 0) {
|
|
796
|
-
// --- top ---
|
|
797
|
-
if (!dirs.includes('top')) {
|
|
798
|
-
gestureElement.style.opacity = '0';
|
|
799
|
-
clearGestureData();
|
|
800
|
-
return;
|
|
801
|
-
}
|
|
802
|
-
gestureElement.style.opacity = '1';
|
|
803
|
-
if (xyAbs === 90) {
|
|
804
|
-
bindGestureData.dir = 'top';
|
|
805
|
-
gestureElement.classList.add('done');
|
|
806
|
-
}
|
|
807
|
-
else {
|
|
808
|
-
bindGestureData.dir = null;
|
|
809
|
-
gestureElement.classList.remove('done');
|
|
810
|
-
}
|
|
811
|
-
gestureElement.style.left = (opt.rect.left + ((opt.rect.width - 20) / 2)).toString() + 'px';
|
|
812
|
-
gestureElement.style.top = (opt.rect.top - 10 + (xyAbs / 1.5)).toString() + 'px';
|
|
813
|
-
gestureElement.style.transform = 'scale(' + (xyAbs / 90).toString() + ')';
|
|
814
|
-
}
|
|
815
|
-
else {
|
|
816
|
-
// --- bottom ---
|
|
817
|
-
if (!dirs.includes('bottom')) {
|
|
818
|
-
gestureElement.style.opacity = '0';
|
|
819
|
-
clearGestureData();
|
|
820
|
-
return;
|
|
821
|
-
}
|
|
822
|
-
gestureElement.style.opacity = '1';
|
|
823
|
-
if (xyAbs === 90) {
|
|
824
|
-
bindGestureData.dir = 'bottom';
|
|
825
|
-
gestureElement.classList.add('done');
|
|
826
|
-
}
|
|
827
|
-
else {
|
|
828
|
-
bindGestureData.dir = null;
|
|
829
|
-
gestureElement.classList.remove('done');
|
|
830
|
-
}
|
|
831
|
-
gestureElement.style.left = (opt.rect.left + ((opt.rect.width - 20) / 2)).toString() + 'px';
|
|
832
|
-
gestureElement.style.top = (opt.rect.top + opt.rect.height - 10 - (xyAbs / 1.5)).toString() + 'px';
|
|
833
|
-
gestureElement.style.transform = 'scale(' + (xyAbs / 90).toString() + ')';
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
if (bindGestureData.xx === bindGestureData.tx && bindGestureData.xy === bindGestureData.ty) {
|
|
838
|
-
// --- 中途终止 ---
|
|
839
|
-
bindGestureData.timers.ani = 0;
|
|
840
|
-
bindGestureData.timers.sleep = window.setTimeout(() => {
|
|
841
|
-
// --- 触摸板 wheel 可能会多次执行,导致圆圈一直在,有缓动 ---
|
|
842
|
-
clearGestureData();
|
|
843
|
-
bindGestureData.timers.sleep = 0;
|
|
844
|
-
gestureElement.style.opacity = '0';
|
|
845
|
-
if (!bindGestureData.dir) {
|
|
846
|
-
return;
|
|
847
|
-
}
|
|
848
|
-
opt.handler(bindGestureData.dir);
|
|
849
|
-
}, 500);
|
|
850
|
-
return;
|
|
851
|
-
}
|
|
852
|
-
bindGestureData.timers.ani = requestAnimationFrame(() => {
|
|
853
|
-
bindGestureAnimation(opt);
|
|
854
|
-
});
|
|
855
|
-
}
|
|
856
|
-
|
|
857
899
|
/**
|
|
858
900
|
* --- 绑定上拉、下拉、左拉、右拉 ---
|
|
859
|
-
* @param
|
|
860
|
-
* @param
|
|
901
|
+
* @param oe 响应事件
|
|
902
|
+
* @param before before 事件,返回 true 则显示 gesture
|
|
903
|
+
* @param handler 执行完毕的话才会回调
|
|
861
904
|
*/
|
|
862
|
-
export function bindGesture(e: MouseEvent | TouchEvent | WheelEvent |
|
|
863
|
-
const
|
|
864
|
-
const el: HTMLElement | undefined = ((e as any).currentTarget as HTMLElement | undefined)
|
|
865
|
-
?? ((e as any).target as HTMLElement | undefined) ?? opt.el;
|
|
905
|
+
export function bindGesture(oe: MouseEvent | TouchEvent | WheelEvent, before: (e: MouseEvent | TouchEvent | WheelEvent, dir: 'top' | 'right' | 'bottom' | 'left') => boolean, handler: (dir: 'top' | 'right' | 'bottom' | 'left') => void | Promise<void>): void {
|
|
906
|
+
const el = oe.currentTarget as HTMLElement | null;
|
|
866
907
|
if (!el) {
|
|
867
908
|
return;
|
|
868
909
|
}
|
|
869
|
-
|
|
870
|
-
if ((
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
return;
|
|
879
|
-
}
|
|
880
|
-
rect = el.getBoundingClientRect();
|
|
881
|
-
}
|
|
882
|
-
const dirs = opt.dirs ?? ['top', 'bottom'];
|
|
883
|
-
if ((e instanceof MouseEvent || e instanceof TouchEvent) && !(e instanceof WheelEvent)) {
|
|
884
|
-
// --- touch / mouse 触发的 ---
|
|
885
|
-
const x: number = e instanceof MouseEvent ? e.clientX : e.touches[0].clientX;
|
|
886
|
-
const y: number = e instanceof MouseEvent ? e.clientY : e.touches[0].clientY;
|
|
887
|
-
let dir: 'top' | 'right' | 'bottom' | 'left' | null = null;
|
|
910
|
+
const rect = el.getBoundingClientRect();
|
|
911
|
+
if ((oe instanceof MouseEvent || oe instanceof TouchEvent) && !(oe instanceof WheelEvent)) {
|
|
912
|
+
// --- touch / mouse 触发的,dir 会和鼠标的 dir 相反,向下拖动是上方加载 ---
|
|
913
|
+
let offset: number = 0;
|
|
914
|
+
let origin: number = 0;
|
|
915
|
+
/** --- 是否第一次执行 move 事件,1-是,0-不是且继续,-1-终止 --- */
|
|
916
|
+
let first = 1;
|
|
917
|
+
/** --- 哪个方向要加载 --- */
|
|
918
|
+
let dir: 'top' | 'right' | 'bottom' | 'left' = 'top';
|
|
888
919
|
/** --- 当前手势方向 --- */
|
|
889
|
-
bindDown(
|
|
890
|
-
move: (e) => {
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
clearTimeout(bindGestureData.timers.sleep);
|
|
898
|
-
bindGestureData.timers.sleep = 0;
|
|
920
|
+
bindDown(oe, {
|
|
921
|
+
move: (e, d) => {
|
|
922
|
+
if (first < 0) {
|
|
923
|
+
if (first > -30) {
|
|
924
|
+
before(e, dir);
|
|
925
|
+
--first;
|
|
926
|
+
}
|
|
927
|
+
return;
|
|
899
928
|
}
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
let xxAbs = Math.abs(xx);
|
|
908
|
-
let xyAbs = Math.abs(xy);
|
|
909
|
-
if ((!dirs.includes('top') && !dirs.includes('bottom')) || ((xxAbs > xyAbs) && (dirs.includes('left') || dirs.includes('right')))) {
|
|
910
|
-
// --- 水平 ---
|
|
911
|
-
if (xx > 0) {
|
|
912
|
-
// --- left ---
|
|
913
|
-
if (!dirs.includes('left')) {
|
|
914
|
-
gestureElement.style.opacity = '0';
|
|
915
|
-
return;
|
|
929
|
+
if (first === 1) {
|
|
930
|
+
// --- 第一次执行,响应 before 判断是否继续执行 ---
|
|
931
|
+
first = 0;
|
|
932
|
+
switch (d) {
|
|
933
|
+
case 'top': {
|
|
934
|
+
dir = 'bottom';
|
|
935
|
+
break;
|
|
916
936
|
}
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
937
|
+
case 'bottom': {
|
|
938
|
+
dir = 'top';
|
|
939
|
+
break;
|
|
940
|
+
}
|
|
941
|
+
case 'left': {
|
|
942
|
+
dir = 'right';
|
|
943
|
+
break;
|
|
944
|
+
}
|
|
945
|
+
default: {
|
|
920
946
|
dir = 'left';
|
|
921
|
-
gestureElement.classList.add('done');
|
|
922
947
|
}
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
948
|
+
}
|
|
949
|
+
if (!before(e, dir)) {
|
|
950
|
+
first = -1;
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
953
|
+
// --- 初始化原点 ---
|
|
954
|
+
switch (dir) {
|
|
955
|
+
case 'top':
|
|
956
|
+
case 'bottom': {
|
|
957
|
+
origin = oe instanceof MouseEvent ? oe.clientY : oe.touches[0].clientY;
|
|
958
|
+
break;
|
|
959
|
+
}
|
|
960
|
+
default: {
|
|
961
|
+
origin = oe instanceof MouseEvent ? oe.clientX : oe.touches[0].clientX;
|
|
926
962
|
}
|
|
927
|
-
gestureElement.style.top = (rect.top + ((rect.height - 20) / 2)).toString() + 'px';
|
|
928
|
-
gestureElement.style.left = (rect.left - 10 + (xxAbs / 1.5)).toString() + 'px';
|
|
929
|
-
gestureElement.style.transform = 'scale(' + (xxAbs / 90).toString() + ')';
|
|
930
963
|
}
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
964
|
+
}
|
|
965
|
+
/** --- 当前坐标 --- */
|
|
966
|
+
let pos: number = 0;
|
|
967
|
+
switch (dir) {
|
|
968
|
+
case 'top':
|
|
969
|
+
case 'bottom': {
|
|
970
|
+
pos = e instanceof MouseEvent ? e.clientY : e.touches[0].clientY;
|
|
971
|
+
if (dir === 'top') {
|
|
972
|
+
offset = pos - origin;
|
|
936
973
|
}
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
974
|
+
else {
|
|
975
|
+
offset = origin - pos;
|
|
976
|
+
}
|
|
977
|
+
break;
|
|
978
|
+
}
|
|
979
|
+
default: {
|
|
980
|
+
pos = e instanceof MouseEvent ? e.clientX : e.touches[0].clientX;
|
|
981
|
+
if (dir === 'left') {
|
|
982
|
+
offset = pos - origin;
|
|
942
983
|
}
|
|
943
984
|
else {
|
|
944
|
-
|
|
945
|
-
gestureElement.classList.remove('done');
|
|
985
|
+
offset = origin - pos;
|
|
946
986
|
}
|
|
947
|
-
gestureElement.style.top = (rect.top + ((rect.height - 20) / 2)).toString() + 'px';
|
|
948
|
-
gestureElement.style.left = (rect.left + rect.width - 10 - (xxAbs / 1.5)).toString() + 'px';
|
|
949
|
-
gestureElement.style.transform = 'scale(' + (xxAbs / 90).toString() + ')';
|
|
950
987
|
}
|
|
951
988
|
}
|
|
989
|
+
|
|
990
|
+
// --- 处理差值 ---
|
|
991
|
+
if (offset >= 90) {
|
|
992
|
+
offset = 90;
|
|
993
|
+
form.elements.gesture.style.opacity = '1';
|
|
994
|
+
form.elements.gesture.classList.add('done');
|
|
995
|
+
}
|
|
952
996
|
else {
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
997
|
+
form.elements.gesture.classList.remove('done');
|
|
998
|
+
if (offset < 0) {
|
|
999
|
+
offset = 0;
|
|
1000
|
+
form.elements.gesture.style.opacity = '0';
|
|
1001
|
+
}
|
|
1002
|
+
else {
|
|
1003
|
+
form.elements.gesture.style.opacity = '1';
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
form.elements.gesture.style.transform = 'scale(' + (offset / 90).toString() + ')';
|
|
1007
|
+
|
|
1008
|
+
// --- 处理标签位置 ---
|
|
1009
|
+
switch (dir) {
|
|
1010
|
+
case 'top':
|
|
1011
|
+
case 'bottom': {
|
|
1012
|
+
form.elements.gesture.style.left = (rect.left + ((rect.width - 20) / 2)).toString() + 'px';
|
|
1013
|
+
if (dir === 'top') {
|
|
1014
|
+
form.elements.gesture.style.top = (rect.top + (offset / 1.5)).toString() + 'px';
|
|
964
1015
|
}
|
|
965
1016
|
else {
|
|
966
|
-
|
|
967
|
-
gestureElement.classList.remove('done');
|
|
1017
|
+
form.elements.gesture.style.top = (rect.bottom - 20 - (offset / 1.5)).toString() + 'px';
|
|
968
1018
|
}
|
|
969
|
-
|
|
970
|
-
gestureElement.style.top = (rect.top - 10 + (xyAbs / 1.5)).toString() + 'px';
|
|
971
|
-
gestureElement.style.transform = 'scale(' + (xyAbs / 90).toString() + ')';
|
|
1019
|
+
break;
|
|
972
1020
|
}
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
if (
|
|
976
|
-
|
|
977
|
-
return;
|
|
978
|
-
}
|
|
979
|
-
gestureElement.style.opacity = '1';
|
|
980
|
-
if (xyAbs > 90) {
|
|
981
|
-
xyAbs = 90;
|
|
982
|
-
dir = 'bottom';
|
|
983
|
-
gestureElement.classList.add('done');
|
|
1021
|
+
default: {
|
|
1022
|
+
form.elements.gesture.style.top = (rect.top + ((rect.height - 20) / 2)).toString() + 'px';
|
|
1023
|
+
if (dir === 'left') {
|
|
1024
|
+
form.elements.gesture.style.left = (rect.left + (offset / 1.5)).toString() + 'px';
|
|
984
1025
|
}
|
|
985
1026
|
else {
|
|
986
|
-
|
|
987
|
-
gestureElement.classList.remove('done');
|
|
1027
|
+
form.elements.gesture.style.left = (rect.right - 20 - (offset / 1.5)).toString() + 'px';
|
|
988
1028
|
}
|
|
989
|
-
gestureElement.style.left = (rect.left + ((rect.width - 20) / 2)).toString() + 'px';
|
|
990
|
-
gestureElement.style.top = (rect.top + rect.height - 10 - (xyAbs / 1.5)).toString() + 'px';
|
|
991
|
-
gestureElement.style.transform = 'scale(' + (xyAbs / 90).toString() + ')';
|
|
992
1029
|
}
|
|
993
1030
|
}
|
|
994
1031
|
},
|
|
995
1032
|
end: (): void => {
|
|
996
|
-
|
|
997
|
-
if (
|
|
1033
|
+
form.elements.gesture.style.opacity = '0';
|
|
1034
|
+
if (offset < 90) {
|
|
998
1035
|
return;
|
|
999
1036
|
}
|
|
1000
|
-
|
|
1037
|
+
handler(dir) as any;
|
|
1001
1038
|
}
|
|
1002
1039
|
});
|
|
1003
1040
|
}
|
|
1004
1041
|
else {
|
|
1005
|
-
// --- wheel
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1042
|
+
// --- wheel 触发 ---
|
|
1043
|
+
(async () => {
|
|
1044
|
+
const now = Date.now();
|
|
1045
|
+
if (now - gestureWheel.last > 250) {
|
|
1046
|
+
// --- 超过 250 毫秒,已经进入下一轮 ---
|
|
1047
|
+
gestureWheel.offset = 0;
|
|
1048
|
+
gestureWheel.done = false;
|
|
1049
|
+
gestureWheel.timer = 0;
|
|
1050
|
+
gestureWheel.firstTimer = false;
|
|
1051
|
+
gestureWheel.dir = '';
|
|
1052
|
+
}
|
|
1053
|
+
// --- 赋值最后执行时间 ---
|
|
1054
|
+
gestureWheel.last = now;
|
|
1055
|
+
if (gestureWheel.firstTimer) {
|
|
1015
1056
|
return;
|
|
1016
1057
|
}
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
x = y;
|
|
1021
|
-
y = 0;
|
|
1058
|
+
// --- 判断本轮是否已经处理结束 ---
|
|
1059
|
+
if (gestureWheel.done) {
|
|
1060
|
+
return;
|
|
1022
1061
|
}
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1062
|
+
// --- 获取滚动 delta 坐标 ---
|
|
1063
|
+
let deltaY = oe.deltaY;
|
|
1064
|
+
let deltaX = oe.deltaX;
|
|
1065
|
+
if (clickgo.dom.is.shift) {
|
|
1066
|
+
deltaY = oe.deltaX;
|
|
1067
|
+
deltaX = oe.deltaY;
|
|
1026
1068
|
}
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1069
|
+
// --- 判断是不是本轮首次滚动 ---
|
|
1070
|
+
if (gestureWheel.dir === '') {
|
|
1071
|
+
// --- 判断滚动方向 ---
|
|
1072
|
+
if (Math.abs(deltaY) > Math.abs(deltaX)) {
|
|
1073
|
+
// --- 竖向滚动 ---
|
|
1074
|
+
if (deltaY < 0) {
|
|
1075
|
+
// --- 向上滚 ---
|
|
1076
|
+
gestureWheel.dir = 'top';
|
|
1077
|
+
}
|
|
1078
|
+
else {
|
|
1079
|
+
// --- 向下滚 ---
|
|
1080
|
+
gestureWheel.dir = 'bottom';
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
else {
|
|
1084
|
+
// --- 横向滚动 ---
|
|
1085
|
+
if (deltaX < 0) {
|
|
1086
|
+
// --- 向左滚 ---
|
|
1087
|
+
gestureWheel.dir = 'left';
|
|
1088
|
+
}
|
|
1089
|
+
else {
|
|
1090
|
+
// --- 向下滚 ---
|
|
1091
|
+
gestureWheel.dir = 'right';
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
// --- 判断是否要显示滚动条 ---
|
|
1095
|
+
if (!before(oe, gestureWheel.dir as any)) {
|
|
1096
|
+
// --- 不显示 ---
|
|
1097
|
+
gestureWheel.done = true;
|
|
1098
|
+
return;
|
|
1099
|
+
}
|
|
1100
|
+
// --- 重置位置 ---
|
|
1101
|
+
form.elements.gesture.style.transform = 'scale(0)';
|
|
1102
|
+
switch (gestureWheel.dir) {
|
|
1103
|
+
case 'top':
|
|
1104
|
+
case 'bottom': {
|
|
1105
|
+
form.elements.gesture.style.left = (rect.left + ((rect.width - 20) / 2)).toString() + 'px';
|
|
1106
|
+
if (gestureWheel.dir === 'top') {
|
|
1107
|
+
form.elements.gesture.style.top = (rect.top + 10).toString() + 'px';
|
|
1108
|
+
}
|
|
1109
|
+
else {
|
|
1110
|
+
form.elements.gesture.style.top = (rect.bottom - 10).toString() + 'px';
|
|
1111
|
+
}
|
|
1112
|
+
break;
|
|
1113
|
+
}
|
|
1114
|
+
default: {
|
|
1115
|
+
form.elements.gesture.style.top = (rect.top + ((rect.height - 20) / 2)).toString() + 'px';
|
|
1116
|
+
if (gestureWheel.dir === 'left') {
|
|
1117
|
+
form.elements.gesture.style.left = (rect.left + 10).toString() + 'px';
|
|
1118
|
+
}
|
|
1119
|
+
else {
|
|
1120
|
+
form.elements.gesture.style.left = (rect.right - 10).toString() + 'px';
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
gestureWheel.firstTimer = true;
|
|
1125
|
+
await tool.sleep(30);
|
|
1126
|
+
gestureWheel.firstTimer = false;
|
|
1127
|
+
form.elements.gesture.classList.add('ani');
|
|
1128
|
+
}
|
|
1129
|
+
// --- 滚动 ---
|
|
1130
|
+
switch (gestureWheel.dir) {
|
|
1131
|
+
case 'top':
|
|
1132
|
+
case 'bottom': {
|
|
1133
|
+
gestureWheel.offset += (gestureWheel.dir === 'top') ? -deltaY : deltaY;
|
|
1134
|
+
break;
|
|
1135
|
+
}
|
|
1136
|
+
default: {
|
|
1137
|
+
gestureWheel.offset += (gestureWheel.dir === 'left') ? -deltaX : deltaX;
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
if (gestureWheel.offset < 0) {
|
|
1141
|
+
// --- 隐藏了,直接 return ---
|
|
1142
|
+
gestureWheel.offset = 0;
|
|
1143
|
+
form.elements.gesture.style.opacity = '0';
|
|
1144
|
+
return;
|
|
1145
|
+
}
|
|
1146
|
+
// --- 显示 gesture 对象 ---
|
|
1147
|
+
form.elements.gesture.style.opacity = '1';
|
|
1148
|
+
let offset = gestureWheel.offset / 1.38;
|
|
1149
|
+
if (offset > 90) {
|
|
1150
|
+
offset = 90;
|
|
1151
|
+
form.elements.gesture.classList.add('done');
|
|
1152
|
+
}
|
|
1153
|
+
else {
|
|
1154
|
+
form.elements.gesture.classList.remove('done');
|
|
1155
|
+
}
|
|
1156
|
+
// --- 处理标签位置(20 像素是 gesture 的宽高) ---
|
|
1157
|
+
form.elements.gesture.style.transform = 'scale(' + (offset / 90).toString() + ')';
|
|
1158
|
+
switch (gestureWheel.dir) {
|
|
1159
|
+
case 'top': {
|
|
1160
|
+
form.elements.gesture.style.top = (rect.top + (offset / 1.5)).toString() + 'px';
|
|
1161
|
+
break;
|
|
1162
|
+
}
|
|
1163
|
+
case 'bottom': {
|
|
1164
|
+
form.elements.gesture.style.top = (rect.bottom - 20 - (offset / 1.5)).toString() + 'px';
|
|
1165
|
+
break;
|
|
1166
|
+
}
|
|
1167
|
+
case 'left': {
|
|
1168
|
+
form.elements.gesture.style.left = (rect.left + (offset / 1.5)).toString() + 'px';
|
|
1169
|
+
break;
|
|
1170
|
+
}
|
|
1171
|
+
default: {
|
|
1172
|
+
form.elements.gesture.style.left = (rect.right - 20 - (offset / 1.5)).toString() + 'px';
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
// --- 看是否要响应 ---
|
|
1176
|
+
clearTimeout(gestureWheel.timer);
|
|
1177
|
+
if (offset < 90) {
|
|
1178
|
+
gestureWheel.timer = window.setTimeout(() => {
|
|
1179
|
+
form.elements.gesture.style.opacity = '0';
|
|
1180
|
+
form.elements.gesture.classList.remove('ani');
|
|
1181
|
+
}, 250);
|
|
1182
|
+
return;
|
|
1183
|
+
}
|
|
1184
|
+
gestureWheel.done = true;
|
|
1185
|
+
handler(gestureWheel.dir as any) as any;
|
|
1186
|
+
await tool.sleep(500);
|
|
1187
|
+
form.elements.gesture.style.opacity = '0';
|
|
1188
|
+
form.elements.gesture.classList.remove('ani');
|
|
1189
|
+
})().catch((e) => {
|
|
1190
|
+
console.log('error', 'dom.bindGesture', e);
|
|
1060
1191
|
});
|
|
1061
1192
|
}
|
|
1062
1193
|
}
|
|
@@ -1151,9 +1282,9 @@ export function bindDrag(e: MouseEvent | TouchEvent, opt: { 'el': HTMLElement; '
|
|
|
1151
1282
|
otop = rect.top;
|
|
1152
1283
|
oleft = rect.left;
|
|
1153
1284
|
},
|
|
1154
|
-
'move': function(
|
|
1155
|
-
const ntop = otop + oy;
|
|
1156
|
-
const nleft = oleft + ox;
|
|
1285
|
+
'move': function(e, o) {
|
|
1286
|
+
const ntop = otop + o.oy;
|
|
1287
|
+
const nleft = oleft + o.ox;
|
|
1157
1288
|
form.moveDrag({
|
|
1158
1289
|
'top': ntop,
|
|
1159
1290
|
'left': nleft,
|
|
@@ -1162,7 +1293,7 @@ export function bindDrag(e: MouseEvent | TouchEvent, opt: { 'el': HTMLElement; '
|
|
|
1162
1293
|
otop = ntop;
|
|
1163
1294
|
oleft = nleft;
|
|
1164
1295
|
// --- 获取当前 element ---
|
|
1165
|
-
const els = document.elementsFromPoint(x, y) as HTMLElement[];
|
|
1296
|
+
const els = document.elementsFromPoint(o.x, o.y) as HTMLElement[];
|
|
1166
1297
|
for (const el of els) {
|
|
1167
1298
|
if (el.dataset.cgDrop === undefined) {
|
|
1168
1299
|
continue;
|
|
@@ -1549,8 +1680,20 @@ export function bindMove(e: MouseEvent | TouchEvent, opt: types.IBindMoveOptions
|
|
|
1549
1680
|
'ox': ox,
|
|
1550
1681
|
'oy': oy
|
|
1551
1682
|
});
|
|
1552
|
-
|
|
1553
|
-
|
|
1683
|
+
opt.move?.(e, {
|
|
1684
|
+
'ox': ox,
|
|
1685
|
+
'oy': oy,
|
|
1686
|
+
'x': x,
|
|
1687
|
+
'y': y,
|
|
1688
|
+
'border': border,
|
|
1689
|
+
'inBorder': {
|
|
1690
|
+
'top': inBorderTop,
|
|
1691
|
+
'right': inBorderRight,
|
|
1692
|
+
'bottom': inBorderBottom,
|
|
1693
|
+
'left': inBorderLeft
|
|
1694
|
+
},
|
|
1695
|
+
'dir': dir
|
|
1696
|
+
});
|
|
1554
1697
|
tx = x;
|
|
1555
1698
|
ty = y;
|
|
1556
1699
|
},
|
|
@@ -1668,22 +1811,22 @@ export function bindResize(e: MouseEvent | TouchEvent, opt: types.IBindResizeOpt
|
|
|
1668
1811
|
'offsetRight': offsetRight,
|
|
1669
1812
|
'offsetBottom': offsetBottom,
|
|
1670
1813
|
'start': opt.start,
|
|
1671
|
-
'move': function(
|
|
1814
|
+
'move': function(e, o) {
|
|
1672
1815
|
if (opt.border === 'tr' || opt.border === 'r' || opt.border === 'rb') {
|
|
1673
|
-
opt.objectWidth! += ox;
|
|
1816
|
+
opt.objectWidth! += o.ox;
|
|
1674
1817
|
}
|
|
1675
1818
|
else if (opt.border === 'bl' || opt.border === 'l' || opt.border === 'lt') {
|
|
1676
|
-
opt.objectWidth! -= ox;
|
|
1677
|
-
opt.objectLeft! += ox;
|
|
1819
|
+
opt.objectWidth! -= o.ox;
|
|
1820
|
+
opt.objectLeft! += o.ox;
|
|
1678
1821
|
}
|
|
1679
1822
|
if (opt.border === 'rb' || opt.border === 'b' || opt.border === 'bl') {
|
|
1680
|
-
opt.objectHeight! += oy;
|
|
1823
|
+
opt.objectHeight! += o.oy;
|
|
1681
1824
|
}
|
|
1682
1825
|
else if (opt.border === 'lt' || opt.border === 't' || opt.border === 'tr') {
|
|
1683
|
-
opt.objectHeight! -= oy;
|
|
1684
|
-
opt.objectTop! += oy;
|
|
1826
|
+
opt.objectHeight! -= o.oy;
|
|
1827
|
+
opt.objectTop! += o.oy;
|
|
1685
1828
|
}
|
|
1686
|
-
opt.move?.(opt.objectLeft!, opt.objectTop!, opt.objectWidth!, opt.objectHeight!, x, y, border);
|
|
1829
|
+
opt.move?.(opt.objectLeft!, opt.objectTop!, opt.objectWidth!, opt.objectHeight!, x, y, o.border);
|
|
1687
1830
|
},
|
|
1688
1831
|
'end': opt.end
|
|
1689
1832
|
});
|
|
@@ -1786,3 +1929,17 @@ export function fullscreen(): boolean {
|
|
|
1786
1929
|
return false;
|
|
1787
1930
|
}
|
|
1788
1931
|
}
|
|
1932
|
+
|
|
1933
|
+
// --- 处理 timer 类,窗体消失时不进行监听 ---
|
|
1934
|
+
document.addEventListener('visibilitychange', function() {
|
|
1935
|
+
if (document.hidden) {
|
|
1936
|
+
// --- 隐藏 ---
|
|
1937
|
+
cancelAnimationFrame(watchStyleTimer);
|
|
1938
|
+
cancelAnimationFrame(watchPropertyTimer);
|
|
1939
|
+
}
|
|
1940
|
+
else {
|
|
1941
|
+
// --- 显示 ---
|
|
1942
|
+
watchStyleTimer = requestAnimationFrame(watchStyleHandler);
|
|
1943
|
+
watchPropertyTimer = requestAnimationFrame(watchPropertyHandler);
|
|
1944
|
+
}
|
|
1945
|
+
});
|