@whitesev/utils 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/Utils.ts CHANGED
@@ -67,7 +67,7 @@ export declare interface Vue2Context extends AnyObject {
67
67
 
68
68
  class Utils {
69
69
  /** 版本号 */
70
- version = "2024.5.28";
70
+ version = "2024.5.30";
71
71
 
72
72
  /**
73
73
  * 在页面中增加style元素,如果html节点存在子节点,添加子节点第一个,反之,添加到html节点的子节点最后一个
@@ -3918,407 +3918,579 @@ class Utils {
3918
3918
  );
3919
3919
  }
3920
3920
  /**
3921
- * 等待指定元素出现,支持多个selector
3922
- * @param nodeSelectors 一个或多个节点选择器,必须为字符串类型
3921
+ * 等待元素出现
3922
+ * @param selector CSS选择器
3923
+ * @param parent (可选)父元素,默认document
3923
3924
  * @example
3924
- * Utils.waitNode("div.xxx").then( element =>{
3925
- * console.log(element); // div.xxx => HTMLElement
3925
+ * Utils.waitNode("div").then( $div =>{
3926
+ * console.log($div); // div => HTMLDivELement
3926
3927
  * })
3928
+ * Utils.waitNode("div",document).then( $div =>{
3929
+ * console.log($div); // div => HTMLDivELement
3930
+ * })
3931
+ */
3932
+ waitNode<T extends Element>(
3933
+ selector: string,
3934
+ parent?: Node | Element | Document | HTMLElement
3935
+ ): Promise<T>;
3936
+ /**
3937
+ * 等待元素出现
3938
+ * @param selectorList CSS选择器数组
3939
+ * @param parent (可选)父元素,默认document
3927
3940
  * @example
3928
- * Utils.waitNode("div.xxx","a.xxx").then( (elementList)=>{
3929
- * console.log(elementList[0]); // div.xxx => HTMLElement
3930
- * console.log(elementList[1]); // a.xxx => HTMLElement
3941
+ * Utils.waitNode(["div"]).then( ([$div]) =>{
3942
+ * console.log($div); // div => HTMLDivELement[]
3943
+ * })
3944
+ * Utils.waitNode(["div"],document).then( ([$div]) =>{
3945
+ * console.log($div); // div => HTMLDivELement[]
3931
3946
  * })
3932
3947
  */
3933
- waitNode<T extends HTMLElement>(nodeSelector: string | [string]): Promise<T>;
3948
+ waitNode<T extends Element[]>(
3949
+ selectorList: string[],
3950
+ parent?: Node | Element | Document | HTMLElement
3951
+ ): Promise<T>;
3934
3952
  /**
3935
- * 等待指定元素出现,支持多个selector
3936
- * @param nodeSelectors 一个或多个节点选择器,必须为字符串类型
3953
+ * 等待元素出现
3954
+ * @param selector CSS选择器
3955
+ * @param parent 父元素,默认document
3956
+ * @param timeout 超时时间,默认0
3937
3957
  * @example
3938
- * Utils.waitNode("div.xxx").then( element =>{
3939
- * console.log(element); // div.xxx => HTMLElement
3958
+ * Utils.waitNode("div",document,1000).then( $div =>{
3959
+ * console.log($div); // $div => HTMLDivELement | null
3940
3960
  * })
3961
+ */
3962
+ waitNode<T extends Element>(
3963
+ selector: string,
3964
+ parent: Node | Element | Document | HTMLElement,
3965
+ timeout: number
3966
+ ): Promise<T | null>;
3967
+ /**
3968
+ * 等待元素出现
3969
+ * @param selectorList CSS选择器数组
3970
+ * @param parent 父元素,默认document
3971
+ * @param timeout 超时时间,默认0
3941
3972
  * @example
3942
- * Utils.waitNode("div.xxx","a.xxx").then( (elementList)=>{
3943
- * console.log(elementList[0]); // div.xxx => HTMLElement
3944
- * console.log(elementList[1]); // a.xxx => HTMLElement
3973
+ * Utils.waitNode(["div"],document,1000).then( ([$div]) =>{
3974
+ * console.log($div); // $div => HTMLDivELement[] | null
3945
3975
  * })
3946
3976
  */
3947
- waitNode<T extends HTMLElement>(...nodeSelectors: string[]): Promise<T[]>;
3977
+ waitNode<T extends Element[]>(
3978
+ selectorList: string[],
3979
+ parent: Node | Element | Document | HTMLElement,
3980
+ timeout: number
3981
+ ): Promise<T | null>;
3948
3982
  /**
3949
- * 等待指定元素出现,支持多个selector
3950
- * @param nodeSelectors 一个或多个节点选择器,必须为字符串类型
3983
+ * 等待元素出现
3984
+ * @param selector CSS选择器
3985
+ * @param timeout 超时时间,默认0
3951
3986
  * @example
3952
- * Utils.waitNode("div.xxx").then( element =>{
3953
- * console.log(element); // div.xxx => HTMLElement
3987
+ * Utils.waitNode("div",1000).then( $div =>{
3988
+ * console.log($div); // $div => HTMLDivELement | null
3954
3989
  * })
3990
+ */
3991
+ waitNode<T extends Element>(
3992
+ selector: string,
3993
+ timeout: number
3994
+ ): Promise<T | null>;
3995
+ /**
3996
+ * 等待元素出现
3997
+ * @param selectorList CSS选择器数组
3998
+ * @param timeout 超时时间,默认0
3955
3999
  * @example
3956
- * Utils.waitNode("div.xxx","a.xxx").then( (elementList)=>{
3957
- * console.log(elementList[0]); // div.xxx => HTMLElement
3958
- * console.log(elementList[1]); // a.xxx => HTMLElement
4000
+ * Utils.waitNode(["div"],1000).then( [$div] =>{
4001
+ * console.log($div); // $div => HTMLDivELement[] | null
3959
4002
  * })
3960
4003
  */
3961
- waitNode<T extends HTMLElement>(...nodeSelectors: string[]): Promise<T | T[]>;
3962
- async waitNode<T extends HTMLElement>(
3963
- ...nodeSelectors: string | string[] | any
3964
- ): Promise<T | T[]> {
3965
- /* 检查每个参数是否为字符串类型 */
3966
- for (let nodeSelector of nodeSelectors) {
3967
- if (typeof nodeSelector !== "string") {
3968
- throw new Error("Utils.waitNode 参数必须都是 string 类型");
4004
+ waitNode<T extends Element[]>(
4005
+ selectorList: string[],
4006
+ timeout: number
4007
+ ): Promise<T | null>;
4008
+ waitNode<T extends Element | Element[]>(...args: any[]): Promise<T | null> {
4009
+ // 过滤掉undefined
4010
+ args = args.filter((arg) => arg !== void 0);
4011
+ let that = this;
4012
+ // 选择器
4013
+ let selector = args[0] as unknown as string | string[];
4014
+ // 父元素(监听的元素)
4015
+ let parent = UtilsCore.document as Node | Element | Document | HTMLElement;
4016
+ // 超时时间
4017
+ let timeout = 0;
4018
+ if (typeof args[0] !== "string" && !Array.isArray(args[0])) {
4019
+ throw new TypeError("Utils.waitNode 第一个参数必须是string|string[]");
4020
+ }
4021
+ if (args.length === 1) {
4022
+ // 上面已做处理
4023
+ } else if (args.length === 2) {
4024
+ let secondParam = args[1];
4025
+ if (typeof secondParam === "number") {
4026
+ // "div",10000
4027
+ timeout = secondParam;
4028
+ } else if (
4029
+ typeof secondParam === "object" &&
4030
+ secondParam instanceof Node
4031
+ ) {
4032
+ // "div",document
4033
+ parent = secondParam;
4034
+ } else {
4035
+ throw new TypeError("Utils.waitNode 第二个参数必须是number|Node");
4036
+ }
4037
+ } else if (args.length === 3) {
4038
+ // "div",document,10000
4039
+ // 第二个参数,parent
4040
+ let secondParam = args[1];
4041
+ // 第三个参数,timeout
4042
+ let thirdParam = args[2];
4043
+ if (typeof secondParam === "object" && secondParam instanceof Node) {
4044
+ parent = secondParam;
4045
+ if (typeof thirdParam === "number") {
4046
+ timeout = thirdParam;
4047
+ } else {
4048
+ throw new TypeError("Utils.waitNode 第三个参数必须是number");
4049
+ }
4050
+ } else {
4051
+ throw new TypeError("Utils.waitNode 第二个参数必须是Node");
3969
4052
  }
4053
+ } else {
4054
+ throw new TypeError("Utils.waitNode 参数个数错误");
3970
4055
  }
3971
- let UtilsContext = this;
3972
4056
  return new Promise((resolve) => {
3973
- /* 防止触发第二次回调 */
3974
- let isReturn = false;
3975
-
3976
- /**
3977
- * 检查所有选择器是否匹配到节点
3978
- * @param observer
3979
- */
3980
- let checkNodes = (observer?: MutationObserver) => {
3981
- let isFind = true;
3982
- let selectNodeArray: HTMLElement[] = [];
3983
- for (let selector of nodeSelectors) {
3984
- let element = document.querySelector(selector) as HTMLElement | null;
3985
- if (!element) {
3986
- /* 没找到,直接退出循环 */
3987
- isFind = false;
3988
- break;
4057
+ function getNode() {
4058
+ if (Array.isArray(selector)) {
4059
+ let result: T[] = [];
4060
+ for (let index = 0; index < selector.length; index++) {
4061
+ let node = (parent as Element).querySelector(selector[index]);
4062
+ if (node) {
4063
+ result.push(node as any);
4064
+ }
3989
4065
  }
3990
- selectNodeArray.push(element);
3991
- }
3992
- if (isFind) {
3993
- isReturn = true;
3994
- observer?.disconnect();
3995
- /* 如果只有一个选择器,那么返回数组中存储的第一个 */
3996
- if (selectNodeArray.length === 1) {
3997
- resolve(selectNodeArray[0] as any);
3998
- } else {
3999
- resolve(selectNodeArray as any);
4066
+ if (result.length === selector.length) {
4067
+ return result;
4000
4068
  }
4069
+ } else {
4070
+ return (parent as Element).querySelector(selector);
4001
4071
  }
4002
- };
4003
-
4004
- /* 在函数开始时检查节点是否已经存在 */
4005
- checkNodes();
4006
-
4007
- /* 监听 DOM 的变化,直到至少有一个节点被匹配到 */
4008
- UtilsContext.mutationObserver(document.documentElement, {
4009
- config: { subtree: true, childList: true, attributes: true },
4010
- callback: (mutations, observer) => {
4011
- if (isReturn) {
4072
+ }
4073
+ let node = getNode();
4074
+ if (node) {
4075
+ resolve(node as any as T);
4076
+ return;
4077
+ }
4078
+ let observer = that.mutationObserver(parent, {
4079
+ config: {
4080
+ subtree: true,
4081
+ childList: true,
4082
+ attributes: true,
4083
+ },
4084
+ callback() {
4085
+ let node = getNode();
4086
+ if (node) {
4087
+ // 取消观察器
4088
+ observer.disconnect();
4089
+ resolve(node as any as T);
4012
4090
  return;
4013
4091
  }
4014
- checkNodes(observer);
4015
4092
  },
4016
4093
  });
4094
+ if (timeout > 0) {
4095
+ setTimeout(() => {
4096
+ // 取消观察器
4097
+ observer.disconnect();
4098
+ resolve(null);
4099
+ }, timeout);
4100
+ }
4017
4101
  });
4018
4102
  }
4019
4103
  /**
4020
- * 在规定时间内,等待任意元素出现,支持多个selector,如果未出现,则关闭监听
4021
- * @param nodeSelectorsList 一个或多个节点选择器,必须为字符串类型
4022
- * @param maxTime (可选)xx毫秒(ms)后关闭监听,默认:0(ms)
4104
+ * 等待任意元素出现
4105
+ * @param selectorList CSS选择器数组
4106
+ * @param parent (可选)监听的父元素
4107
+ * @example
4108
+ * Utils.waitAnyNode(["div","div"]).then( $div =>{
4109
+ * console.log($div); // $div => HTMLDivELement 这里是第一个
4110
+ * })
4111
+ * Utils.waitAnyNode(["a","div"],document).then( $a =>{
4112
+ * console.log($a); // $a => HTMLAnchorElement 这里是第一个
4113
+ * })
4114
+ */
4115
+ waitAnyNode<T extends Element>(
4116
+ selectorList: string[],
4117
+ parent?: Node | Element | Document | HTMLElement
4118
+ ): Promise<T>;
4119
+ /**
4120
+ * 等待任意元素出现
4121
+ * @param selectorList CSS选择器数组
4122
+ * @param parent 父元素,默认document
4123
+ * @param timeout 超时时间,默认0
4023
4124
  * @example
4024
- * Utils.waitNodeWithInterval("a.xxx",30000).then(element=>{
4025
- * console.log(element);
4125
+ * Utils.waitAnyNode(["div","div"],document,10000).then( $div =>{
4126
+ * console.log($div); // $div => HTMLDivELement | null
4026
4127
  * })
4128
+ */
4129
+ waitAnyNode<T extends Element>(
4130
+ selectorList: string[],
4131
+ parent: Node | Element | Document | HTMLElement,
4132
+ timeout: number
4133
+ ): Promise<T | null>;
4134
+ /**
4135
+ * 等待任意元素出现
4136
+ * @param selectorList CSS选择器数组
4137
+ * @param timeout 超时时间,默认0
4027
4138
  * @example
4028
- * Utils.waitNodeWithInterval(["div.xxx","a.xxx"],30000).then(elementList=>{
4029
- * console.log(elementList[0]); // div.xxx => HTMLElement
4030
- * console.log(elementList[1]); // a.xxx => HTMLElement
4139
+ * Utils.waitAnyNode(["div","div"],10000).then( $div =>{
4140
+ * console.log($div); // $div => HTMLDivELement | null
4031
4141
  * })
4032
4142
  */
4033
- waitNodeWithInterval<T extends HTMLElement>(
4034
- nodeSelectorsList?: string[] | string,
4035
- maxTime?: number
4036
- ): Promise<T | T[]>;
4037
- waitNodeWithInterval<T extends HTMLElement>(
4038
- nodeSelectorsList: string[] | string = [],
4039
- maxTime: number = 0
4040
- ): Promise<T | T[]> {
4041
- let UtilsContext = this;
4042
- let nodeSelectors: string[] = [];
4043
- /* 检查每个参数是否为字符串类型 */
4044
- if (Array.isArray(nodeSelectorsList)) {
4045
- for (let nodeSelector of nodeSelectorsList) {
4046
- if (typeof nodeSelector !== "string") {
4047
- throw new Error(
4048
- "Utils.waitNodeWithInterval 参数nodeSelectorsList必须为 string[] 类型"
4049
- );
4143
+ waitAnyNode<T extends Element>(
4144
+ selectorList: string[],
4145
+ timeout: number
4146
+ ): Promise<T | null>;
4147
+ waitAnyNode<T extends Element>(...args: any[]): Promise<T | null> {
4148
+ // 过滤掉undefined
4149
+ args = args.filter((arg) => arg !== void 0);
4150
+ let that = this;
4151
+ // 选择器
4152
+ let selectorList = args[0] as unknown as string[];
4153
+ // 父元素(监听的元素)
4154
+ let parent = UtilsCore.document as Node | Element | Document | HTMLElement;
4155
+ // 超时时间
4156
+ let timeout = 0;
4157
+ if (typeof args[0] !== "object" && !Array.isArray(args[0])) {
4158
+ throw new TypeError("Utils.waitAnyNode 第一个参数必须是string[]");
4159
+ }
4160
+ if (args.length === 1) {
4161
+ // 上面已做处理
4162
+ } else if (args.length === 2) {
4163
+ let secondParam = args[1];
4164
+ if (typeof secondParam === "number") {
4165
+ // "div",10000
4166
+ timeout = secondParam;
4167
+ } else if (
4168
+ typeof secondParam === "object" &&
4169
+ secondParam instanceof Node
4170
+ ) {
4171
+ // "div",document
4172
+ parent = secondParam;
4173
+ } else {
4174
+ throw new TypeError("Utils.waitAnyNode 第二个参数必须是number|Node");
4175
+ }
4176
+ } else if (args.length === 3) {
4177
+ // "div",document,10000
4178
+ // 第二个参数,parent
4179
+ let secondParam = args[1];
4180
+ // 第三个参数,timeout
4181
+ let thirdParam = args[2];
4182
+ if (typeof secondParam === "object" && secondParam instanceof Node) {
4183
+ parent = secondParam;
4184
+ if (typeof thirdParam === "number") {
4185
+ timeout = thirdParam;
4186
+ } else {
4187
+ throw new TypeError("Utils.waitAnyNode 第三个参数必须是number");
4050
4188
  }
4189
+ } else {
4190
+ throw new TypeError("Utils.waitAnyNode 第二个参数必须是Node");
4051
4191
  }
4052
- nodeSelectors = nodeSelectorsList;
4053
4192
  } else {
4054
- nodeSelectors.push(nodeSelectorsList);
4193
+ throw new TypeError("Utils.waitAnyNode 参数个数错误");
4055
4194
  }
4056
-
4057
- return new Promise((resolve, reject) => {
4058
- /* 防止触发第二次回调 */
4059
- let isReturn = false;
4060
-
4061
- /* 检查所有选择器是否匹配到节点 */
4062
- let checkNodes = (observer?: MutationObserver) => {
4063
- let isFind = true;
4064
- let selectNodeArray = [];
4065
- for (let selector of nodeSelectors) {
4066
- let element = document.querySelector(selector);
4067
- if (!element) {
4068
- /* 没找到,直接退出循环 */
4069
- isFind = false;
4070
- break;
4071
- }
4072
- selectNodeArray.push(element);
4073
- }
4074
- if (isFind) {
4075
- isReturn = true;
4076
- observer?.disconnect();
4077
- /* 如果只有一个选择器,那么返回数组中存储的第一个 */
4078
- if (selectNodeArray.length === 1) {
4079
- resolve(selectNodeArray[0] as any);
4080
- } else {
4081
- resolve(selectNodeArray as any);
4082
- }
4083
- }
4084
- };
4085
-
4086
- /* 在函数开始时检查节点是否已经存在 */
4087
- checkNodes();
4088
-
4089
- /* 监听 DOM 的变化,直到至少有一个节点被匹配到 */
4090
- let mutationObserver = UtilsContext.mutationObserver(
4091
- document.documentElement,
4092
- {
4093
- config: { subtree: true, childList: true, attributes: true },
4094
- callback: (mutations, observer) => {
4095
- if (isReturn) {
4096
- return;
4097
- }
4098
- checkNodes(observer);
4099
- },
4100
- }
4101
- );
4102
- setTimeout(() => {
4103
- mutationObserver.disconnect();
4104
- reject();
4105
- }, maxTime);
4195
+ let promiseList = selectorList.map((selector) => {
4196
+ return that.waitNode<T>(selector, parent, timeout);
4106
4197
  });
4198
+ return Promise.any(promiseList);
4107
4199
  }
4108
4200
 
4109
4201
  /**
4110
- * 等待任意元素出现,支持多个selector
4111
- * @param nodeSelectors 一个或多个节点选择器,必须为字符串类型
4202
+ * 等待元素数组出现
4203
+ * @param selector CSS选择器
4204
+ * @param parent (可选)监听的父元素
4112
4205
  * @example
4113
- * Utils.waitAnyNode("div.xxx","a.xxx").then( element =>{
4114
- * console.log(element); // a.xxx => HTMLElement
4206
+ * Utils.waitNodeList("div").then( $result =>{
4207
+ * console.log($result); // $result => NodeListOf<HTMLDivElement>
4208
+ * })
4209
+ * Utils.waitNodeList("div",document).then( $result =>{
4210
+ * console.log($result); // $result => NodeListOf<HTMLDivElement>
4115
4211
  * })
4116
4212
  */
4117
- waitAnyNode<T extends HTMLElement>(...nodeSelectors: any[]): Promise<T>;
4118
- waitAnyNode<T extends HTMLElement>(...nodeSelectors: any[]): Promise<T> {
4119
- let UtilsContext = this;
4120
- /* 检查每个参数是否为字符串类型 */
4121
- for (let nodeSelector of nodeSelectors) {
4122
- if (typeof nodeSelector !== "string") {
4123
- throw new Error("Utils.waitNode 参数必须为 ...string 类型");
4124
- }
4125
- }
4126
-
4127
- return new Promise((resolve) => {
4128
- /* 防止触发第二次回调 */
4129
- let isReturn = false;
4130
-
4131
- /* 检查所有选择器是否存在任意匹配到元素 */
4132
- let checkNodes = (observer?: MutationObserver) => {
4133
- let selectNode = null;
4134
- for (let selector of nodeSelectors) {
4135
- selectNode = document.querySelector(selector);
4136
- if (selectNode) {
4137
- /* 找到,退出循环 */
4138
- break;
4139
- }
4140
- }
4141
- if (selectNode) {
4142
- isReturn = true;
4143
- observer?.disconnect();
4144
- resolve(selectNode);
4145
- }
4146
- };
4147
-
4148
- /* 在函数开始时检查节点是否已经存在 */
4149
- checkNodes();
4150
-
4151
- /* 监听 DOM 的变化,直到至少有一个节点被匹配到 */
4152
- UtilsContext.mutationObserver(document.documentElement, {
4153
- config: { subtree: true, childList: true, attributes: true },
4154
- callback: (mutations, observer) => {
4155
- if (isReturn) {
4156
- return;
4157
- }
4158
- checkNodes(observer);
4159
- },
4160
- });
4161
- });
4162
- }
4213
+ waitNodeList<T extends NodeListOf<Element>>(
4214
+ selector: string,
4215
+ parent?: Node | Element | Document | HTMLElement
4216
+ ): Promise<T>;
4163
4217
  /**
4164
- * 等待指定元素出现
4165
- * @param nodeSelectors
4166
- * @returns 当nodeSelectors为数组多个时,
4167
- * 返回如:[ NodeList, NodeList ],
4168
- * 当nodeSelectors为单个时,
4169
- * 返回如:NodeList。
4170
- * NodeList元素与页面存在强绑定,当已获取该NodeList,但是页面中却删除了,该元素在NodeList中会被自动删除
4218
+ * 等待元素数组出现
4219
+ * @param selectorList CSS选择器数组
4220
+ * @param parent (可选)监听的父元素
4171
4221
  * @example
4172
- * Utils.waitNodeList("div.xxx").then( nodeList =>{
4173
- * console.log(nodeList) // div.xxx => NodeList
4222
+ * Utils.waitNodeList(["div"]).then( $result =>{
4223
+ * console.log($result); // $result => NodeListOf<HTMLDivElement>[]
4224
+ * })
4225
+ * Utils.waitNodeList(["div"],document).then( $result =>{
4226
+ * console.log($result); // $result => NodeListOf<HTMLDivElement>[]
4174
4227
  * })
4228
+ */
4229
+ waitNodeList<T extends NodeListOf<Element>[]>(
4230
+ selectorList: string[],
4231
+ parent?: Node | Element | Document | HTMLElement
4232
+ ): Promise<T>;
4233
+ /**
4234
+ * 等待元素数组出现
4235
+ * @param selector CSS选择器
4236
+ * @param parent 监听的父元素
4237
+ * @param timeout 超时时间,默认0
4175
4238
  * @example
4176
- * Utils.waitNodeList("div.xxx","a.xxx").then( nodeListArray =>{
4177
- * console.log(nodeListArray[0]) // div.xxx => NodeList
4178
- * console.log(nodeListArray[1]) // a.xxx => NodeList
4239
+ * Utils.waitNodeList("div",document,10000).then( $result =>{
4240
+ * console.log($result); // $result => NodeListOf<HTMLDivElement> | null
4179
4241
  * })
4180
4242
  */
4181
- waitNodeList<T extends HTMLElement>(nodeSelector: string): Promise<T>;
4182
- /**
4183
- * 等待指定元素出现,支持多个selector
4184
- * @param nodeSelectors
4185
- * @returns 当nodeSelectors为数组多个时,
4186
- * 返回如:[ NodeList, NodeList ],
4187
- * 当nodeSelectors为单个时,
4188
- * 返回如:NodeList。
4189
- * NodeList元素与页面存在强绑定,当已获取该NodeList,但是页面中却删除了,该元素在NodeList中会被自动删除
4243
+ waitNodeList<T extends NodeListOf<Element>>(
4244
+ selector: string,
4245
+ parent: Node | Element | Document | HTMLElement,
4246
+ timeout: number
4247
+ ): Promise<T | null>;
4248
+ /**
4249
+ * 等待元素数组出现
4250
+ * @param selectorList CSS选择器数组
4251
+ * @param parent 监听的父元素
4252
+ * @param timeout 超时时间,默认0
4190
4253
  * @example
4191
- * Utils.waitNodeList("div.xxx").then( nodeList =>{
4192
- * console.log(nodeList) // div.xxx => NodeList
4254
+ * Utils.waitNodeList(["div"],document,10000).then( $result =>{
4255
+ * console.log($result); // $result => NodeListOf<HTMLDivElement>[] | null
4193
4256
  * })
4257
+ */
4258
+ waitNodeList<T extends NodeListOf<Element>[]>(
4259
+ selectorList: string[],
4260
+ parent: Node | Element | Document | HTMLElement,
4261
+ timeout: number
4262
+ ): Promise<T | null>;
4263
+ /**
4264
+ * 等待元素数组出现
4265
+ * @param selector CSS选择器数组
4266
+ * @param timeout 超时时间,默认0
4194
4267
  * @example
4195
- * Utils.waitNodeList("div.xxx","a.xxx").then( nodeListArray =>{
4196
- * console.log(nodeListArray[0]) // div.xxx => NodeList
4197
- * console.log(nodeListArray[1]) // a.xxx => NodeList
4268
+ * Utils.waitNodeList("div",10000).then( $result =>{
4269
+ * console.log($result); // $result => NodeListOf<HTMLDivElement> | null
4198
4270
  * })
4199
4271
  */
4200
- waitNodeList<T extends HTMLElement>(
4201
- ...nodeSelectors: string[]
4202
- ): Promise<NodeListOf<T>[]>;
4203
- waitNodeList<T extends HTMLElement>(
4204
- ...nodeSelectors: string[]
4205
- ): Promise<NodeListOf<T>[]> {
4206
- let UtilsContext = this;
4207
- /* 检查每个参数是否为字符串类型 */
4208
- for (let nodeSelector of nodeSelectors) {
4209
- if (typeof nodeSelector !== "string") {
4210
- throw new Error("Utils.waitNode 参数必须为 ...string 类型");
4272
+ waitNodeList<T extends NodeListOf<Element>>(
4273
+ selector: string[],
4274
+ timeout: number
4275
+ ): Promise<T | null>;
4276
+ /**
4277
+ * 等待元素数组出现
4278
+ * @param selectorList CSS选择器数组
4279
+ * @param timeout 超时时间,默认0
4280
+ * @example
4281
+ * Utils.waitNodeList(["div"],10000).then( $result =>{
4282
+ * console.log($result); // $result => NodeListOf<HTMLDivElement>[] | null
4283
+ * })
4284
+ */
4285
+ waitNodeList<T extends NodeListOf<Element>>(
4286
+ selectorList: string[],
4287
+ timeout: number
4288
+ ): Promise<T[] | null>;
4289
+ waitNodeList<T extends NodeListOf<Element> | NodeListOf<Element>[]>(
4290
+ ...args: any[]
4291
+ ): Promise<T | null> {
4292
+ // 过滤掉undefined
4293
+ args = args.filter((arg) => arg !== void 0);
4294
+ let that = this;
4295
+ // 选择器数组
4296
+ let selector = args[0] as unknown as string | string[];
4297
+ // 父元素(监听的元素)
4298
+ let parent = UtilsCore.document as Node | Element | Document | HTMLElement;
4299
+ // 超时时间
4300
+ let timeout = 0;
4301
+ if (typeof args[0] !== "string" && !Array.isArray(args[0])) {
4302
+ throw new TypeError("Utils.waitNodeList 第一个参数必须是string|string[]");
4303
+ }
4304
+ if (args.length === 1) {
4305
+ // 上面已做处理
4306
+ } else if (args.length === 2) {
4307
+ let secondParam = args[1];
4308
+ if (typeof secondParam === "number") {
4309
+ // "div",10000
4310
+ timeout = secondParam;
4311
+ } else if (
4312
+ typeof secondParam === "object" &&
4313
+ secondParam instanceof Node
4314
+ ) {
4315
+ // "div",document
4316
+ parent = secondParam;
4317
+ } else {
4318
+ throw new TypeError("Utils.waitNodeList 第二个参数必须是number|Node");
4319
+ }
4320
+ } else if (args.length === 3) {
4321
+ // "div",document,10000
4322
+ // 第二个参数,parent
4323
+ let secondParam = args[1];
4324
+ // 第三个参数,timeout
4325
+ let thirdParam = args[2];
4326
+ if (typeof secondParam === "object" && secondParam instanceof Node) {
4327
+ parent = secondParam;
4328
+ if (typeof thirdParam === "number") {
4329
+ timeout = thirdParam;
4330
+ } else {
4331
+ throw new TypeError("Utils.waitNodeList 第三个参数必须是number");
4332
+ }
4333
+ } else {
4334
+ throw new TypeError("Utils.waitNodeList 第二个参数必须是Node");
4211
4335
  }
4336
+ } else {
4337
+ throw new TypeError("Utils.waitNodeList 参数个数错误");
4212
4338
  }
4213
-
4214
4339
  return new Promise((resolve) => {
4215
- /* 防止触发第二次回调 */
4216
- let isReturn = false;
4217
-
4218
- /* 检查所有选择器是否匹配到节点 */
4219
- let checkNodes = (observer?: MutationObserver) => {
4220
- let isFind = true;
4221
- let selectNodes = [];
4222
- for (let selector of nodeSelectors) {
4223
- let nodeList = document.querySelectorAll(selector);
4224
- if (nodeList.length === 0) {
4225
- /* 没找到,直接退出循环 */
4226
- isFind = false;
4227
- break;
4340
+ function getNodeList() {
4341
+ if (Array.isArray(selector)) {
4342
+ let result: T[] = [];
4343
+ for (let index = 0; index < selector.length; index++) {
4344
+ let nodeList = (parent as Element).querySelectorAll(
4345
+ selector[index]
4346
+ ) as T;
4347
+ if (nodeList.length) {
4348
+ result.push(nodeList);
4349
+ }
4228
4350
  }
4229
- selectNodes.push(nodeList);
4230
- }
4231
- if (isFind) {
4232
- isReturn = true;
4233
- observer?.disconnect();
4234
- /* 如果只有一个选择器,那么返回第一个 */
4235
- if (selectNodes.length === 1) {
4236
- resolve(selectNodes[0] as any);
4237
- } else {
4238
- resolve(selectNodes as any);
4351
+ if (result.length === selector.length) {
4352
+ return result;
4353
+ }
4354
+ } else {
4355
+ let nodeList = (parent as Element).querySelectorAll(selector) as T;
4356
+ if (nodeList.length) {
4357
+ return nodeList;
4239
4358
  }
4240
4359
  }
4241
- };
4242
-
4243
- /* 在函数开始时检查节点是否已经存在 */
4244
- checkNodes();
4245
-
4246
- /* 监听 DOM 的变化,直到至少有一个节点被匹配到 */
4247
- UtilsContext.mutationObserver(document.documentElement, {
4248
- config: { subtree: true, childList: true, attributes: true },
4249
- callback: (mutations, observer) => {
4250
- if (isReturn) {
4360
+ }
4361
+ let nodeList = getNodeList();
4362
+ if (nodeList) {
4363
+ resolve(nodeList as T);
4364
+ return;
4365
+ }
4366
+ let observer = that.mutationObserver(parent, {
4367
+ config: {
4368
+ subtree: true,
4369
+ childList: true,
4370
+ attributes: true,
4371
+ },
4372
+ callback() {
4373
+ let node = getNodeList();
4374
+ if (node) {
4375
+ // 取消观察器
4376
+ observer.disconnect();
4377
+ resolve(node as T);
4251
4378
  return;
4252
4379
  }
4253
- checkNodes(observer);
4254
4380
  },
4255
4381
  });
4382
+ if (timeout > 0) {
4383
+ setTimeout(() => {
4384
+ // 取消观察器
4385
+ observer.disconnect();
4386
+ resolve(null);
4387
+ }, timeout);
4388
+ }
4256
4389
  });
4257
4390
  }
4258
4391
  /**
4259
- * 等待任意元素出现,支持多个selector
4260
- * @param nodeSelectors
4261
- * @returns 返回NodeList
4262
- * NodeList元素与页面存在强绑定,当已获取该NodeList,但是页面中却删除了,该元素在NodeList中会被自动删除
4392
+ * 等待任意元素数组出现
4393
+ * @param selectorList CSS选择器数组
4394
+ * @param parent (可选)监听的父元素
4263
4395
  * @example
4264
- * Utils.waitAnyNodeList("div.xxx").then( nodeList =>{
4265
- * console.log(nodeList) // div.xxx => NodeList
4396
+ * Utils.waitAnyNodeList(["div","a"]).then( $result =>{
4397
+ * console.log($result); // $result => NodeListOf<HTMLDivElement>
4266
4398
  * })
4399
+ * Utils.waitAnyNodeList(["div","a"],document).then( $result =>{
4400
+ * console.log($result); // $result => NodeListOf<HTMLDivElement>
4401
+ * })
4402
+ */
4403
+ waitAnyNodeList<T extends Element>(
4404
+ selectorList: string[],
4405
+ parent?: Node | Element | Document | HTMLElement
4406
+ ): Promise<NodeListOf<T>>;
4407
+ /**
4408
+ * 等待任意元素数组出现
4409
+ * @param selectorList CSS选择器数组
4410
+ * @param parent 父元素,默认document
4411
+ * @param timeout 超时时间,默认0
4267
4412
  * @example
4268
- * Utils.waitAnyNodeList("div.xxx","a.xxx").then( nodeList =>{
4269
- * console.log(nodeList) // a.xxx => NodeList
4413
+ * Utils.waitAnyNodeList(["div","a"],document,10000).then( $result =>{
4414
+ * console.log($result); // $result => NodeListOf<HTMLDivElement> | null
4270
4415
  * })
4271
4416
  */
4272
- waitAnyNodeList<T extends HTMLElement>(
4273
- ...nodeSelectors: string[]
4274
- ): Promise<NodeListOf<T>[]>;
4275
- waitAnyNodeList<T extends HTMLElement>(
4276
- ...nodeSelectors: string[]
4277
- ): Promise<NodeListOf<T>[]> {
4278
- let UtilsContext = this;
4279
- /* 检查每个参数是否为字符串类型 */
4280
- for (let nodeSelector of nodeSelectors) {
4281
- if (typeof nodeSelector !== "string") {
4282
- throw new Error("Utils.waitNode 参数必须为 ...string 类型");
4417
+ waitAnyNodeList<T extends Element>(
4418
+ selectorList: string[],
4419
+ parent: Node | Element | Document | HTMLElement,
4420
+ timeout: number
4421
+ ): Promise<NodeListOf<T> | null>;
4422
+ /**
4423
+ * 等待任意元素出现
4424
+ * @param selectorList CSS选择器数组
4425
+ * @param timeout 超时时间,默认0
4426
+ * @example
4427
+ * Utils.waitAnyNodeList(["div","div"],10000).then( $result =>{
4428
+ * console.log($result); // $result => NodeListOf<HTMLDivElement> | null
4429
+ * })
4430
+ */
4431
+ waitAnyNodeList<T extends Element>(
4432
+ selectorList: string[],
4433
+ timeout: number
4434
+ ): Promise<NodeListOf<T> | null>;
4435
+ waitAnyNodeList<T extends Element>(
4436
+ ...args: any[]
4437
+ ): Promise<NodeListOf<T> | null> {
4438
+ // 过滤掉undefined
4439
+ args = args.filter((arg) => arg !== void 0);
4440
+ let that = this;
4441
+ // 选择器数组
4442
+ let selectorList = args[0] as unknown as string[];
4443
+ // 父元素(监听的元素)
4444
+ let parent = UtilsCore.document as Node | Element | Document | HTMLElement;
4445
+ // 超时时间
4446
+ let timeout = 0;
4447
+ if (!Array.isArray(args[0])) {
4448
+ throw new TypeError("Utils.waitAnyNodeList 第一个参数必须是string[]");
4449
+ }
4450
+ if (args.length === 1) {
4451
+ // 上面已做处理
4452
+ } else if (args.length === 2) {
4453
+ let secondParam = args[1];
4454
+ if (typeof secondParam === "number") {
4455
+ // "div",10000
4456
+ timeout = secondParam;
4457
+ } else if (
4458
+ typeof secondParam === "object" &&
4459
+ secondParam instanceof Node
4460
+ ) {
4461
+ // "div",document
4462
+ parent = secondParam;
4463
+ } else {
4464
+ throw new TypeError(
4465
+ "Utils.waitAnyNodeList 第二个参数必须是number|Node"
4466
+ );
4283
4467
  }
4284
- }
4285
-
4286
- return new Promise((resolve) => {
4287
- /* 防止触发第二次回调 */
4288
- let isReturn = false;
4289
-
4290
- /* 检查所有选择器是否匹配到节点 */
4291
- let checkNodes = (observer?: MutationObserver) => {
4292
- let selectNodes = [];
4293
- for (let selector of nodeSelectors) {
4294
- selectNodes = document.querySelectorAll(selector) as any;
4295
- if (selectNodes.length) {
4296
- /* 找到,退出循环 */
4297
- break;
4298
- }
4299
- }
4300
- if (selectNodes.length) {
4301
- isReturn = true;
4302
- observer?.disconnect();
4303
- resolve(selectNodes);
4468
+ } else if (args.length === 3) {
4469
+ // "div",document,10000
4470
+ // 第二个参数,parent
4471
+ let secondParam = args[1];
4472
+ // 第三个参数,timeout
4473
+ let thirdParam = args[2];
4474
+ if (typeof secondParam === "object" && secondParam instanceof Node) {
4475
+ parent = secondParam;
4476
+ if (typeof thirdParam === "number") {
4477
+ timeout = thirdParam;
4478
+ } else {
4479
+ throw new TypeError("Utils.waitAnyNodeList 第三个参数必须是number");
4304
4480
  }
4305
- };
4306
-
4307
- /* 在函数开始时检查节点是否已经存在 */
4308
- checkNodes();
4481
+ } else {
4482
+ throw new TypeError("Utils.waitAnyNodeList 第二个参数必须是Node");
4483
+ }
4484
+ } else {
4485
+ throw new TypeError("Utils.waitAnyNodeList 参数个数错误");
4486
+ }
4309
4487
 
4310
- /* 监听 DOM 的变化,直到至少有一个节点被匹配到 */
4311
- UtilsContext.mutationObserver(document.documentElement, {
4312
- config: { subtree: true, childList: true, attributes: true },
4313
- callback: (mutations, observer) => {
4314
- if (isReturn) {
4315
- return;
4316
- }
4317
- checkNodes(observer);
4318
- },
4319
- });
4488
+ let promiseList = selectorList.map((selector) => {
4489
+ return that.waitNodeList<NodeListOf<T>>(selector, parent, timeout);
4320
4490
  });
4491
+ return Promise.any(promiseList);
4321
4492
  }
4493
+
4322
4494
  /**
4323
4495
  * 等待对象上的属性出现
4324
4496
  * @param checkObj 检查的对象