@whitesev/utils 2.11.11 → 2.11.13
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/index.amd.js +220 -62
- package/dist/index.amd.js.map +1 -1
- package/dist/index.amd.min.js +1 -1
- package/dist/index.amd.min.js.map +1 -1
- package/dist/index.cjs.js +220 -62
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.cjs.min.js +1 -1
- package/dist/index.cjs.min.js.map +1 -1
- package/dist/index.esm.js +220 -62
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +1 -1
- package/dist/index.esm.min.js.map +1 -1
- package/dist/index.iife.js +220 -62
- package/dist/index.iife.js.map +1 -1
- package/dist/index.iife.min.js +1 -1
- package/dist/index.iife.min.js.map +1 -1
- package/dist/index.system.js +220 -62
- package/dist/index.system.js.map +1 -1
- package/dist/index.system.min.js +1 -1
- package/dist/index.system.min.js.map +1 -1
- package/dist/index.umd.js +220 -62
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +1 -1
- package/dist/index.umd.min.js.map +1 -1
- package/dist/types/src/Dictionary.d.ts +13 -2
- package/dist/types/src/Utils.d.ts +37 -11
- package/dist/types/src/ajaxHooker/ajaxHooker.d.ts +8 -2
- package/dist/types/src/ajaxHooker/ajaxHooker1.2.4.d.ts +8 -2
- package/dist/types/src/types/Httpx.d.ts +16 -16
- package/dist/types/src/types/ajaxHooker.d.ts +92 -56
- package/package.json +3 -4
- package/src/Dictionary.ts +24 -3
- package/src/Httpx.ts +18 -18
- package/src/LockFunction.ts +3 -6
- package/src/Utils.ts +85 -53
- package/src/ajaxHooker/ajaxHooker.js +55 -5
- package/src/ajaxHooker/ajaxHooker1.2.4.js +58 -14
- package/src/types/Httpx.d.ts +16 -16
- package/src/types/ajaxHooker.d.ts +92 -56
package/dist/index.cjs.js
CHANGED
|
@@ -239,7 +239,7 @@ const clearTimeout$1 = (timerId) => loadOrReturnBroker().clearTimeout(timerId);
|
|
|
239
239
|
const setInterval$1 = (...args) => loadOrReturnBroker().setInterval(...args);
|
|
240
240
|
const setTimeout$1 = (...args) => loadOrReturnBroker().setTimeout(...args);
|
|
241
241
|
|
|
242
|
-
const version = "2.11.
|
|
242
|
+
const version = "2.11.13";
|
|
243
243
|
|
|
244
244
|
/* eslint-disable */
|
|
245
245
|
// ==UserScript==
|
|
@@ -374,8 +374,12 @@ const ajaxHooker = function () {
|
|
|
374
374
|
}));
|
|
375
375
|
}
|
|
376
376
|
waitForRequestKeys() {
|
|
377
|
+
/**
|
|
378
|
+
* @type {Set<typeof hookInst>}
|
|
379
|
+
*/
|
|
380
|
+
const winHookInsts = win.__ajaxHooker.hookInsts;
|
|
377
381
|
if (!this.request.async) {
|
|
378
|
-
|
|
382
|
+
winHookInsts.forEach(({ hookFns, filters }) => {
|
|
379
383
|
if (this.shouldFilter(filters))
|
|
380
384
|
return;
|
|
381
385
|
hookFns.forEach((fn) => {
|
|
@@ -391,10 +395,10 @@ const ajaxHooker = function () {
|
|
|
391
395
|
}
|
|
392
396
|
const promises = [];
|
|
393
397
|
const ignoreKeys = new Set(["type", "async", "response"]);
|
|
394
|
-
|
|
398
|
+
winHookInsts.forEach(({ hookFns, filters }) => {
|
|
395
399
|
if (this.shouldFilter(filters))
|
|
396
400
|
return;
|
|
397
|
-
promises.push(Promise.all(hookFns.map((fn) => catchError(fn, this.request))).then(() => {
|
|
401
|
+
promises.push(Promise.all(hookFns.map((fn, index) => catchError(fn, this.request, index))).then(() => {
|
|
398
402
|
const requestKeys = [];
|
|
399
403
|
for (const key in this.request)
|
|
400
404
|
!ignoreKeys.has(key) && requestKeys.push(key);
|
|
@@ -816,11 +820,52 @@ const ajaxHooker = function () {
|
|
|
816
820
|
});
|
|
817
821
|
});
|
|
818
822
|
}
|
|
823
|
+
/**
|
|
824
|
+
*
|
|
825
|
+
* @type {import("./../types/ajaxHooker.d.ts").UtilsAjaxHookResult["removeHook"]}
|
|
826
|
+
*/
|
|
827
|
+
const removeHook = (fn, onlyRemove = false) => {
|
|
828
|
+
let flag = false;
|
|
829
|
+
for (let index = hookInst.hookFns.length - 1; index >= 0; index--) {
|
|
830
|
+
const __fn__ = hookInst.hookFns[index];
|
|
831
|
+
if (fn === __fn__) {
|
|
832
|
+
hookInst.hookFns.splice(index, 1);
|
|
833
|
+
flag = true;
|
|
834
|
+
if (onlyRemove) {
|
|
835
|
+
break;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
return flag;
|
|
840
|
+
};
|
|
841
|
+
/**
|
|
842
|
+
*
|
|
843
|
+
* @type {import("./../types/ajaxHooker.d.ts").UtilsAjaxHookResult["removeFilter"]}
|
|
844
|
+
*/
|
|
845
|
+
const removeFilter = () => {
|
|
846
|
+
if (Array.isArray(hookInst.filters)) {
|
|
847
|
+
hookInst.filters.length = 0;
|
|
848
|
+
}
|
|
849
|
+
else {
|
|
850
|
+
hookInst.filters = [];
|
|
851
|
+
}
|
|
852
|
+
};
|
|
819
853
|
return {
|
|
820
|
-
hook: (fn) =>
|
|
854
|
+
hook: (fn) => {
|
|
855
|
+
hookInst.hookFns.push(fn);
|
|
856
|
+
return {
|
|
857
|
+
remove: () => {
|
|
858
|
+
return removeHook(fn, true);
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
},
|
|
821
862
|
filter: (arr) => {
|
|
822
|
-
if (Array.isArray(arr))
|
|
863
|
+
if (Array.isArray(arr)) {
|
|
823
864
|
hookInst.filters = arr;
|
|
865
|
+
}
|
|
866
|
+
return {
|
|
867
|
+
remove: removeFilter
|
|
868
|
+
};
|
|
824
869
|
},
|
|
825
870
|
protect: () => {
|
|
826
871
|
readonly(win, "XMLHttpRequest", winAh.fakeXHR);
|
|
@@ -836,6 +881,8 @@ const ajaxHooker = function () {
|
|
|
836
881
|
delete win.__ajaxHooker;
|
|
837
882
|
}
|
|
838
883
|
},
|
|
884
|
+
removeHook: removeHook,
|
|
885
|
+
removeFilter: removeFilter
|
|
839
886
|
};
|
|
840
887
|
};
|
|
841
888
|
|
|
@@ -1234,10 +1281,50 @@ const AjaxHooker1_2_4 = function () {
|
|
|
1234
1281
|
Object.keys(realXhr).forEach((key) => (fakeXhr[key] = realXhr[key]));
|
|
1235
1282
|
fakeXhr.prototype = realXhr.prototype;
|
|
1236
1283
|
win.fetch = fakeFetch;
|
|
1284
|
+
/**
|
|
1285
|
+
*
|
|
1286
|
+
* @type {import("./../types/ajaxHooker.d.ts").UtilsAjaxHookResult["removeHook"]}
|
|
1287
|
+
*/
|
|
1288
|
+
const removeHook = (fn, onlyRemove = false) => {
|
|
1289
|
+
let flag = false;
|
|
1290
|
+
for (let index = hookFns.length - 1; index >= 0; index--) {
|
|
1291
|
+
const __fn__ = hookFns[index];
|
|
1292
|
+
if (fn === __fn__) {
|
|
1293
|
+
hookFns.splice(index, 1);
|
|
1294
|
+
flag = true;
|
|
1295
|
+
if (onlyRemove) {
|
|
1296
|
+
break;
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
return flag;
|
|
1301
|
+
};
|
|
1302
|
+
/**
|
|
1303
|
+
*
|
|
1304
|
+
* @type {import("./../types/ajaxHooker.d.ts").UtilsAjaxHookResult["removeFilter"]}
|
|
1305
|
+
*/
|
|
1306
|
+
const removeFilter = () => {
|
|
1307
|
+
if (Array.isArray(filter)) {
|
|
1308
|
+
filter.length = 0;
|
|
1309
|
+
}
|
|
1310
|
+
else {
|
|
1311
|
+
filter = void 0;
|
|
1312
|
+
}
|
|
1313
|
+
};
|
|
1237
1314
|
return {
|
|
1238
|
-
hook: (fn) =>
|
|
1315
|
+
hook: (fn) => {
|
|
1316
|
+
hookFns.push(fn);
|
|
1317
|
+
return {
|
|
1318
|
+
remove: () => {
|
|
1319
|
+
return removeHook(fn, true);
|
|
1320
|
+
}
|
|
1321
|
+
};
|
|
1322
|
+
},
|
|
1239
1323
|
filter: (arr) => {
|
|
1240
1324
|
filter = Array.isArray(arr) && arr.map(toFilterObj);
|
|
1325
|
+
return {
|
|
1326
|
+
remove: removeFilter
|
|
1327
|
+
};
|
|
1241
1328
|
},
|
|
1242
1329
|
protect: () => {
|
|
1243
1330
|
readonly(win, "XMLHttpRequest", fakeXhr);
|
|
@@ -1247,6 +1334,8 @@ const AjaxHooker1_2_4 = function () {
|
|
|
1247
1334
|
writable(win, "XMLHttpRequest", realXhr);
|
|
1248
1335
|
writable(win, "fetch", realFetch);
|
|
1249
1336
|
},
|
|
1337
|
+
removeHook: removeHook,
|
|
1338
|
+
removeFilter: removeFilter
|
|
1250
1339
|
};
|
|
1251
1340
|
})();
|
|
1252
1341
|
};
|
|
@@ -1831,13 +1920,25 @@ class UtilsDictionary {
|
|
|
1831
1920
|
}
|
|
1832
1921
|
/**
|
|
1833
1922
|
* 迭代字典
|
|
1834
|
-
* @param
|
|
1923
|
+
* @param cb 回调函数
|
|
1835
1924
|
*/
|
|
1836
|
-
forEach(
|
|
1925
|
+
forEach(cb) {
|
|
1837
1926
|
this.items.forEach((value, key) => {
|
|
1838
|
-
|
|
1927
|
+
cb(value, key, this);
|
|
1839
1928
|
});
|
|
1840
1929
|
}
|
|
1930
|
+
/**
|
|
1931
|
+
* 找到字典中对应的键和值
|
|
1932
|
+
* @param cb 回调函数
|
|
1933
|
+
*/
|
|
1934
|
+
find(cb) {
|
|
1935
|
+
for (const [key, value] of this.items.entries()) {
|
|
1936
|
+
const result = cb(value, key, this);
|
|
1937
|
+
if (result) {
|
|
1938
|
+
return result;
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1841
1942
|
/**
|
|
1842
1943
|
* 检查已有的键中是否以xx开头
|
|
1843
1944
|
* @param key 需要匹配的键
|
|
@@ -2671,42 +2772,42 @@ class Httpx {
|
|
|
2671
2772
|
const method = requestOption.method;
|
|
2672
2773
|
if (method === "GET" || method === "HEAD") {
|
|
2673
2774
|
// GET类型,data如果有,那么需要转为searchParams
|
|
2674
|
-
const
|
|
2775
|
+
const urlInst = new URL(requestOption.url);
|
|
2675
2776
|
let urlSearch = "";
|
|
2676
|
-
let
|
|
2777
|
+
let deleteData = false;
|
|
2677
2778
|
if (typeof requestOption.data === "string") {
|
|
2678
|
-
|
|
2779
|
+
deleteData = true;
|
|
2679
2780
|
urlSearch = requestOption.data;
|
|
2680
2781
|
}
|
|
2681
2782
|
else if (typeof requestOption.data === "object") {
|
|
2682
|
-
|
|
2783
|
+
deleteData = true;
|
|
2683
2784
|
// URLSearchParams参数可以转普通的string:string,包括FormData
|
|
2684
2785
|
const searchParams = new URLSearchParams(requestOption.data);
|
|
2685
2786
|
urlSearch = searchParams.toString();
|
|
2686
2787
|
}
|
|
2687
|
-
if (
|
|
2788
|
+
if (deleteData) {
|
|
2688
2789
|
// GET/HEAD请求不支持data参数
|
|
2689
2790
|
// 对data进行处理了才可以删除
|
|
2690
2791
|
Reflect.deleteProperty(requestOption, "data");
|
|
2691
2792
|
}
|
|
2692
|
-
if (urlSearch != "") {
|
|
2693
|
-
if (
|
|
2793
|
+
if (urlSearch.trim() != "") {
|
|
2794
|
+
if (urlInst.search.trim() === "") {
|
|
2694
2795
|
// url没有search参数,直接覆盖
|
|
2695
|
-
|
|
2796
|
+
urlInst.search = urlSearch;
|
|
2696
2797
|
}
|
|
2697
2798
|
else {
|
|
2698
2799
|
// 有search参数
|
|
2699
|
-
if (
|
|
2800
|
+
if (urlInst.search.trim().endsWith("&")) {
|
|
2700
2801
|
// xxx=xxx&
|
|
2701
|
-
|
|
2802
|
+
urlInst.search = urlInst.search + urlSearch;
|
|
2702
2803
|
}
|
|
2703
2804
|
else {
|
|
2704
2805
|
// xxx=xxx&xxx=
|
|
2705
|
-
|
|
2806
|
+
urlInst.search = `${urlInst.search}&${urlSearch}`;
|
|
2706
2807
|
}
|
|
2707
2808
|
}
|
|
2708
2809
|
}
|
|
2709
|
-
requestOption.url =
|
|
2810
|
+
requestOption.url = urlInst.toString();
|
|
2710
2811
|
}
|
|
2711
2812
|
else if (method === "POST" && requestOption.headers != null) {
|
|
2712
2813
|
// POST类型,data如果是FormData,那么需要转为string
|
|
@@ -2716,10 +2817,10 @@ class Httpx {
|
|
|
2716
2817
|
typeof requestOption.headers[headerKey] === "string");
|
|
2717
2818
|
});
|
|
2718
2819
|
if (ContentTypeIndex !== -1) {
|
|
2719
|
-
const
|
|
2720
|
-
const
|
|
2820
|
+
const contentTypeKey = headersKeyList[ContentTypeIndex];
|
|
2821
|
+
const contentType = requestOption.headers[contentTypeKey].toLowerCase();
|
|
2721
2822
|
// 设置了Content-Type
|
|
2722
|
-
if (
|
|
2823
|
+
if (contentType.includes("application/json")) {
|
|
2723
2824
|
// application/json
|
|
2724
2825
|
if (requestOption.data instanceof FormData) {
|
|
2725
2826
|
const entries = {};
|
|
@@ -2732,16 +2833,16 @@ class Httpx {
|
|
|
2732
2833
|
requestOption.data = JSON.stringify(requestOption.data);
|
|
2733
2834
|
}
|
|
2734
2835
|
}
|
|
2735
|
-
else if (
|
|
2836
|
+
else if (contentType.includes("application/x-www-form-urlencoded")) {
|
|
2736
2837
|
// application/x-www-form-urlencoded
|
|
2737
2838
|
if (typeof requestOption.data === "object") {
|
|
2738
2839
|
requestOption.data = new URLSearchParams(requestOption.data).toString();
|
|
2739
2840
|
}
|
|
2740
2841
|
}
|
|
2741
|
-
else if (
|
|
2842
|
+
else if (contentType.includes("multipart/form-data")) {
|
|
2742
2843
|
// multipart/form-data
|
|
2743
2844
|
if (requestOption.data instanceof FormData) {
|
|
2744
|
-
Reflect.deleteProperty(requestOption.headers,
|
|
2845
|
+
Reflect.deleteProperty(requestOption.headers, contentTypeKey);
|
|
2745
2846
|
}
|
|
2746
2847
|
}
|
|
2747
2848
|
}
|
|
@@ -5699,20 +5800,25 @@ class Utils {
|
|
|
5699
5800
|
}
|
|
5700
5801
|
/**
|
|
5701
5802
|
* ajax劫持库,支持xhr和fetch劫持。
|
|
5702
|
-
* +
|
|
5703
|
-
* +
|
|
5704
|
-
* +
|
|
5705
|
-
* +
|
|
5706
|
-
* +
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5803
|
+
* + 来源: https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
|
|
5804
|
+
* + 作者: cxxjackie
|
|
5805
|
+
* + 实现方式: Proxy
|
|
5806
|
+
* + 版本: `1.4.8`
|
|
5807
|
+
* + 文档: https://scriptcat.org/zh-CN/script-show-page/637/
|
|
5808
|
+
*/
|
|
5809
|
+
ajaxHooker = () => {
|
|
5810
|
+
return ajaxHooker();
|
|
5811
|
+
};
|
|
5812
|
+
/**
|
|
5813
|
+
* ajax劫持库,支持xhr和fetch劫持。
|
|
5814
|
+
* + 来源: https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
|
|
5815
|
+
* + 作者: cxxjackie
|
|
5816
|
+
* + 实现方式: Object.defineProperty
|
|
5817
|
+
* + 版本: `1.2.4`
|
|
5818
|
+
* + 文档: https://scriptcat.org/zh-CN/script-show-page/637/
|
|
5819
|
+
*/
|
|
5820
|
+
oldAjaxHooker = () => {
|
|
5821
|
+
return AjaxHooker1_2_4();
|
|
5716
5822
|
};
|
|
5717
5823
|
canvasClickByPosition(canvasElement, clientX = 0, clientY = 0, view = this.windowApi.window) {
|
|
5718
5824
|
if (!(canvasElement instanceof HTMLCanvasElement)) {
|
|
@@ -7237,6 +7343,26 @@ class Utils {
|
|
|
7237
7343
|
}
|
|
7238
7344
|
return content;
|
|
7239
7345
|
}
|
|
7346
|
+
/**
|
|
7347
|
+
* 监听页面元素改变并处理
|
|
7348
|
+
* @param target 需要监听的元素,如果不存在,可以等待它出现
|
|
7349
|
+
* @param observer_config MutationObserver的配置
|
|
7350
|
+
* @example
|
|
7351
|
+
Utils.mutationObserver(document.querySelector("div.xxxx"),{
|
|
7352
|
+
"callback":(mutations, observer)=>{},
|
|
7353
|
+
"config":{childList:true,attributes:true}
|
|
7354
|
+
});
|
|
7355
|
+
* @example
|
|
7356
|
+
Utils.mutationObserver(document.querySelectorAll("div.xxxx"),{
|
|
7357
|
+
"callback":(mutations, observer)=>{},
|
|
7358
|
+
"config":{childList:true,attributes:true}}
|
|
7359
|
+
);
|
|
7360
|
+
* @example
|
|
7361
|
+
Utils.mutationObserver($("div.xxxx"),{
|
|
7362
|
+
"callback":(mutations, observer)=>{},
|
|
7363
|
+
"config":{childList:true,attributes:true}}
|
|
7364
|
+
);
|
|
7365
|
+
**/
|
|
7240
7366
|
mutationObserver(target, observer_config) {
|
|
7241
7367
|
const that = this;
|
|
7242
7368
|
const default_obverser_config = {
|
|
@@ -7279,16 +7405,24 @@ class Utils {
|
|
|
7279
7405
|
characterDataOldValue: void 0,
|
|
7280
7406
|
},
|
|
7281
7407
|
immediate: false,
|
|
7408
|
+
once: false,
|
|
7282
7409
|
};
|
|
7283
7410
|
observer_config = that.assign(default_obverser_config, observer_config);
|
|
7284
7411
|
const windowMutationObserver = this.windowApi.window.MutationObserver ||
|
|
7285
7412
|
this.windowApi.window.webkitMutationObserver ||
|
|
7286
7413
|
this.windowApi.window.MozMutationObserver;
|
|
7287
7414
|
// 观察者对象
|
|
7288
|
-
const
|
|
7415
|
+
const handler = (mutations, observer) => {
|
|
7416
|
+
if (observer_config.once) {
|
|
7417
|
+
// 仅触发一次
|
|
7418
|
+
observer.disconnect();
|
|
7419
|
+
}
|
|
7289
7420
|
if (typeof observer_config.callback === "function") {
|
|
7290
7421
|
observer_config.callback(mutations, observer);
|
|
7291
7422
|
}
|
|
7423
|
+
};
|
|
7424
|
+
const mutationObserver = new windowMutationObserver(function (mutations, observer) {
|
|
7425
|
+
handler(mutations, observer);
|
|
7292
7426
|
});
|
|
7293
7427
|
if (Array.isArray(target) || target instanceof NodeList) {
|
|
7294
7428
|
// 传入的是数组或者元素数组
|
|
@@ -7297,7 +7431,7 @@ class Utils {
|
|
|
7297
7431
|
});
|
|
7298
7432
|
}
|
|
7299
7433
|
else if (that.isJQuery(target)) {
|
|
7300
|
-
|
|
7434
|
+
// 传入的参数是jQuery对象
|
|
7301
7435
|
target.each((_, item) => {
|
|
7302
7436
|
mutationObserver.observe(item, observer_config.config);
|
|
7303
7437
|
});
|
|
@@ -7306,16 +7440,14 @@ class Utils {
|
|
|
7306
7440
|
mutationObserver.observe(target, observer_config.config);
|
|
7307
7441
|
}
|
|
7308
7442
|
if (observer_config.immediate) {
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
observer_config.callback([], mutationObserver);
|
|
7312
|
-
}
|
|
7443
|
+
// 主动触发一次
|
|
7444
|
+
handler([], mutationObserver);
|
|
7313
7445
|
}
|
|
7314
7446
|
return mutationObserver;
|
|
7315
7447
|
}
|
|
7316
7448
|
/**
|
|
7317
7449
|
* 使用观察器观察元素出现在视图内,出现的话触发回调
|
|
7318
|
-
* @param
|
|
7450
|
+
* @param $el 目标元素
|
|
7319
7451
|
* @param callback 触发的回调
|
|
7320
7452
|
* @param options 观察器配置
|
|
7321
7453
|
* @example
|
|
@@ -7323,34 +7455,47 @@ class Utils {
|
|
|
7323
7455
|
* console.log("该元素出现在视图内");
|
|
7324
7456
|
* }))
|
|
7325
7457
|
*/
|
|
7326
|
-
mutationVisible(
|
|
7458
|
+
mutationVisible($el, callback, options) {
|
|
7327
7459
|
if (typeof IntersectionObserver === "undefined") {
|
|
7328
7460
|
throw new TypeError("IntersectionObserver is not defined");
|
|
7329
7461
|
}
|
|
7330
|
-
if (
|
|
7462
|
+
if ($el == null) {
|
|
7331
7463
|
throw new TypeError("mutatuinVisible target is null");
|
|
7332
7464
|
}
|
|
7465
|
+
options = options || {};
|
|
7333
7466
|
let defaultOptions = {
|
|
7334
7467
|
root: null,
|
|
7335
7468
|
rootMargin: "0px 0px 0px 0px",
|
|
7336
7469
|
threshold: [0.01, 0.99],
|
|
7337
7470
|
};
|
|
7338
|
-
defaultOptions = this.assign(defaultOptions, options
|
|
7471
|
+
defaultOptions = this.assign(defaultOptions, options);
|
|
7472
|
+
const handler = (entries, observer) => {
|
|
7473
|
+
if (options.once) {
|
|
7474
|
+
// 仅触发一次
|
|
7475
|
+
observer.disconnect();
|
|
7476
|
+
}
|
|
7477
|
+
if (typeof callback === "function") {
|
|
7478
|
+
callback(entries, observer);
|
|
7479
|
+
}
|
|
7480
|
+
};
|
|
7339
7481
|
const intersectionObserver = new IntersectionObserver((entries, observer) => {
|
|
7340
7482
|
if (entries[0].isIntersecting) {
|
|
7341
|
-
|
|
7342
|
-
callback(entries, observer);
|
|
7343
|
-
}
|
|
7483
|
+
handler(entries, observer);
|
|
7344
7484
|
}
|
|
7345
7485
|
}, defaultOptions);
|
|
7346
|
-
if (Array.isArray(
|
|
7347
|
-
|
|
7348
|
-
intersectionObserver.observe(
|
|
7486
|
+
if (Array.isArray($el)) {
|
|
7487
|
+
$el.forEach(($elItem) => {
|
|
7488
|
+
intersectionObserver.observe($elItem);
|
|
7349
7489
|
});
|
|
7350
7490
|
}
|
|
7351
7491
|
else {
|
|
7352
|
-
intersectionObserver.observe(
|
|
7492
|
+
intersectionObserver.observe($el);
|
|
7353
7493
|
}
|
|
7494
|
+
if (options.immediate) {
|
|
7495
|
+
// 立即触发
|
|
7496
|
+
handler([], intersectionObserver);
|
|
7497
|
+
}
|
|
7498
|
+
return intersectionObserver;
|
|
7354
7499
|
}
|
|
7355
7500
|
/**
|
|
7356
7501
|
* 去除全局window下的Utils,返回控制权
|
|
@@ -8139,12 +8284,25 @@ class Utils {
|
|
|
8139
8284
|
}
|
|
8140
8285
|
/**
|
|
8141
8286
|
* 将UrlSearchParams格式的字符串转为对象
|
|
8287
|
+
* @param searhParamsStr 字符串或对象
|
|
8288
|
+
* @example
|
|
8289
|
+
* Utils.searchParamStrToObj("xxx=xx&xx2=xx2")
|
|
8290
|
+
* @example
|
|
8291
|
+
* Utils.searchParamStrToObj(new URLSearchParams({
|
|
8292
|
+
* test1: 1,
|
|
8293
|
+
* test2: 2
|
|
8294
|
+
* }))
|
|
8142
8295
|
*/
|
|
8143
8296
|
searchParamStrToObj(searhParamsStr) {
|
|
8144
|
-
|
|
8145
|
-
|
|
8297
|
+
const params = {};
|
|
8298
|
+
if (searhParamsStr == null) {
|
|
8299
|
+
return params;
|
|
8146
8300
|
}
|
|
8147
|
-
|
|
8301
|
+
const urlSearchParams = searhParamsStr instanceof URLSearchParams ? searhParamsStr : new URLSearchParams(searhParamsStr);
|
|
8302
|
+
urlSearchParams.forEach((value, key) => {
|
|
8303
|
+
Reflect.set(params, key, value);
|
|
8304
|
+
});
|
|
8305
|
+
return params;
|
|
8148
8306
|
}
|
|
8149
8307
|
/**
|
|
8150
8308
|
* 提供一个封装了 try-catch 的函数,可以执行传入的函数并捕获其可能抛出的错误,并通过传入的错误处理函数进行处理。
|