@whitesev/utils 2.11.7 → 2.11.9

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
@@ -817,30 +817,33 @@ class Utils {
817
817
  * 元素是否可见
818
818
  * @param $el
819
819
  * @param $css
820
+ * @returns
821
+ * + true 可见
822
+ * + false 不可见
820
823
  */
821
- function isVisibleNode($el: Element, $css: CSSStyleDeclaration): boolean {
824
+ const isVisibleNode = function ($css: CSSStyleDeclaration, $el: Element): boolean {
822
825
  let flag = true;
823
- if (typeof $el.checkVisibility === "function") {
824
- flag = $el.checkVisibility();
826
+ if (!($el instanceof HTMLElement)) {
827
+ flag = false;
825
828
  } else {
826
- flag =
827
- $css.position !== "static" && $css.display !== "none" && $css.visibility !== "hidden" && $css.opacity !== "0";
828
- }
829
- if (flag) {
830
- // css样式上可见
831
- // 再判断宽高
832
- const rect = $el.getBoundingClientRect();
833
- // 确保该元素的中心点在屏幕内
834
- flag = rect.width > 0 && rect.height > 0 && rect.x > 0 && rect.y > 0;
829
+ if (typeof $el.checkVisibility === "function") {
830
+ flag = $el.checkVisibility();
831
+ } else {
832
+ flag =
833
+ $css.position !== "static" &&
834
+ $css.display !== "none" &&
835
+ $css.visibility !== "hidden" &&
836
+ $css.opacity !== "0";
837
+ }
835
838
  }
836
839
  return flag;
837
- }
840
+ };
838
841
  /**
839
842
  * 查询元素的z-index
840
843
  * 并比较值是否是已获取的最大值
841
844
  * @param $el
842
845
  */
843
- function queryMaxZIndex($el: Element) {
846
+ const queryMaxZIndex = function ($el: Element) {
844
847
  if (typeof ignoreCallBack === "function") {
845
848
  const ignoreResult = ignoreCallBack($el);
846
849
  if (typeof ignoreResult === "boolean" && !ignoreResult) {
@@ -848,9 +851,9 @@ class Utils {
848
851
  }
849
852
  }
850
853
  /** 元素的样式 */
851
- const nodeStyle = that.windowApi.window.getComputedStyle($el);
854
+ const nodeStyle = that.windowApi.globalThis.getComputedStyle($el);
852
855
  /* 不对position为static和display为none的元素进行获取它们的z-index */
853
- if (isVisibleNode($el, nodeStyle)) {
856
+ if (isVisibleNode(nodeStyle, $el)) {
854
857
  const nodeZIndex = parseInt(nodeStyle.zIndex);
855
858
  if (!isNaN(nodeZIndex)) {
856
859
  if (nodeZIndex > zIndex) {
@@ -866,7 +869,7 @@ class Utils {
866
869
  });
867
870
  }
868
871
  }
869
- }
872
+ };
870
873
  target.querySelectorAll("*").forEach(($elItem) => {
871
874
  queryMaxZIndex($elItem);
872
875
  });
@@ -883,18 +886,24 @@ class Utils {
883
886
  /**
884
887
  * 获取页面的坐标中最大的z-index的元素信息
885
888
  *
886
- * 其中坐标为
887
- *
888
- * + 左上角(宽: 1/8,高: 1/8)
889
- * + 右上角(宽: 7/8,高: 1/8)
890
- * + 左下角(宽: 1/8,高: 7/8)
891
- * + 右下角(宽: 7/8,高: 7/8)
892
- * + 中间(宽: 1/2,高: 1/2)
889
+ * 矩阵坐标计算
893
890
  * @param $el 仅检测目标元素最大的z-index(自动往上层找)
894
891
  * @param deviation 将对所有获取到的z-index处理偏移量(增加或减少),默认为10
892
+ * @example
893
+ * Utils.getMaxZIndexNodeInfoFromPoint(document.querySelector("a"));
894
+ * @example
895
+ * Utils.getMaxZIndexNodeInfoFromPoint(document.querySelector("a"), 20);
896
+ * @example
897
+ * Utils.getMaxZIndexNodeInfoFromPoint([document.querySelector("a"), document.querySelector("div")]);
898
+ * @example
899
+ * Utils.getMaxZIndexNodeInfoFromPoint({x: 500, y: 500});
900
+ * @example
901
+ * Utils.getMaxZIndexNodeInfoFromPoint({x: 500, y: 500}, 20);
902
+ * @example
903
+ * Utils.getMaxZIndexNodeInfoFromPoint(() => {x: 500, y: 500}, 20);
895
904
  */
896
905
  getMaxZIndexNodeInfoFromPoint(
897
- $el?: IFunction<HTMLElement | HTMLElement[]>,
906
+ $el?: IFunction<IArray<HTMLElement> | IArray<{ x: number; y: number }>>,
898
907
  deviation?: number
899
908
  ): {
900
909
  /** 处理了偏移量后的z-index值 */
@@ -913,14 +922,10 @@ class Utils {
913
922
  /**
914
923
  * 获取页面的坐标中最大的z-index的元素信息
915
924
  *
916
- * 其中坐标为
917
- *
918
- * + 左上角(宽: 1/8,高: 1/8)
919
- * + 右上角(宽: 7/8,高: 1/8)
920
- * + 左下角(宽: 1/8,高: 7/8)
921
- * + 右下角(宽: 7/8,高: 7/8)
922
- * + 中间(宽: 1/2,高: 1/2)
925
+ * 矩阵坐标计算
923
926
  * @param deviation 将对所有获取到的z-index处理偏移量(增加或减少)
927
+ * @example
928
+ * Utils.getMaxZIndexNodeInfoFromPoint(20);
924
929
  */
925
930
  getMaxZIndexNodeInfoFromPoint(deviation: IFunction<number>): {
926
931
  /** 处理了偏移量后的z-index值 */
@@ -937,7 +942,7 @@ class Utils {
937
942
  positionY: number;
938
943
  }[];
939
944
  getMaxZIndexNodeInfoFromPoint(
940
- $el?: IFunction<HTMLElement | HTMLElement[] | number>,
945
+ $el?: IFunction<IArray<HTMLElement> | number | IArray<{ x: number; y: number }>>,
941
946
  deviation?: number
942
947
  ): {
943
948
  /** 处理了偏移量后的z-index值 */
@@ -963,33 +968,34 @@ class Utils {
963
968
  if (typeof deviation !== "number" || Number.isNaN(deviation)) {
964
969
  deviation = 10;
965
970
  }
966
- const leftTop = {
967
- x: globalThis.innerWidth * (1 / 8),
968
- y: globalThis.innerHeight * (1 / 8),
969
- };
970
- const leftBottom = {
971
- x: globalThis.innerWidth * (1 / 8),
972
- y: globalThis.innerHeight * (7 / 8),
973
- };
974
- const rightTop = {
975
- x: globalThis.innerWidth * (7 / 8),
976
- y: globalThis.innerHeight * (1 / 8),
977
- };
978
- const rightBottom = {
979
- x: globalThis.innerWidth * (7 / 8),
980
- y: globalThis.innerHeight * (7 / 8),
981
- };
982
- const center = {
983
- x: globalThis.innerWidth / 2,
984
- y: globalThis.innerHeight / 2,
985
- };
986
- const delayHandlerElementPostionList: ({ x: number; y: number } | HTMLElement)[] = [
987
- leftTop,
988
- leftBottom,
989
- rightTop,
990
- rightBottom,
991
- center,
992
- ];
971
+ /** 坐标偏移 */
972
+ const positionDistance = 10;
973
+ const defaultCalcPostion: {
974
+ x: number;
975
+ y: number;
976
+ }[] = [];
977
+ const maxPostionX = globalThis.innerWidth;
978
+ const maxPostionY = globalThis.innerHeight;
979
+ const gridXCount = 8;
980
+ const gridYCount = 8;
981
+ for (let i = 0; i < gridXCount; i++) {
982
+ for (let j = 0; j < gridYCount; j++) {
983
+ const positionX = globalThis.innerWidth * (i / gridXCount) + positionDistance;
984
+ const positionY = globalThis.innerHeight * (j / gridYCount) + positionDistance;
985
+ const position: (typeof defaultCalcPostion)[0] = {
986
+ x: positionX,
987
+ y: positionY,
988
+ };
989
+ if (position.x > maxPostionX) {
990
+ position.x = maxPostionX;
991
+ }
992
+ if (position.y > maxPostionY) {
993
+ position.y = maxPostionY;
994
+ }
995
+ defaultCalcPostion.push(position);
996
+ }
997
+ }
998
+ const delayHandlerElementPostionList: ({ x: number; y: number } | HTMLElement)[] = defaultCalcPostion;
993
999
  if ($el) {
994
1000
  delayHandlerElementPostionList.length = 0;
995
1001
  if (Array.isArray($el)) {
@@ -1000,55 +1006,77 @@ class Utils {
1000
1006
  }
1001
1007
  const positionInfoList = delayHandlerElementPostionList
1002
1008
  .map((position) => {
1003
- let positionNode: Element | null;
1009
+ let $position: Element | null;
1004
1010
  let positionX: number;
1005
1011
  let positionY: number;
1006
1012
  if (position instanceof HTMLElement) {
1007
- positionNode = position;
1013
+ $position = position;
1008
1014
  const nodeRect = position.getBoundingClientRect();
1009
1015
  positionX = nodeRect.x + nodeRect.width / 2;
1010
1016
  positionY = nodeRect.y + nodeRect.height / 2;
1011
1017
  } else {
1012
- positionNode = document.elementFromPoint(position.x, position.y);
1018
+ $position = document.elementFromPoint(position.x, position.y);
1013
1019
  positionX = position.x;
1014
1020
  positionY = position.y;
1015
1021
  }
1016
- const shadowRoot = positionNode?.shadowRoot;
1022
+ const shadowRoot = $position?.shadowRoot;
1017
1023
  if (shadowRoot) {
1018
- positionNode = shadowRoot.elementFromPoint(positionX, positionY);
1024
+ // 处理ShadowRoot
1025
+ $position = shadowRoot.elementFromPoint(positionX, positionY);
1019
1026
  }
1020
- if (positionNode instanceof HTMLStyleElement) return;
1021
- if (positionNode instanceof HTMLScriptElement) return;
1022
- if (positionNode instanceof HTMLMetaElement) return;
1023
- if (positionNode instanceof HTMLHeadElement) return;
1024
- if (!(positionNode instanceof HTMLElement)) return;
1025
- let parent: HTMLElement | null = positionNode;
1027
+ if (!($position instanceof HTMLElement)) return;
1028
+ let $parent: HTMLElement | null = $position;
1026
1029
  let zIndex = 0;
1027
- let maxZIndexNode: HTMLElement | null = null;
1028
- while (parent) {
1029
- const nodeStyle = globalThis.getComputedStyle(parent);
1030
+ let $maxZIndexNode: HTMLElement | null = null;
1031
+ let rect = {
1032
+ x: 0,
1033
+ y: 0,
1034
+ width: 0,
1035
+ height: 0,
1036
+ top: 0,
1037
+ right: 0,
1038
+ bottom: 0,
1039
+ left: 0,
1040
+ } as Omit<DOMRect, "toJSON">;
1041
+ while ($parent) {
1042
+ const nodeStyle = globalThis.getComputedStyle($parent);
1030
1043
  const nodeZIndex = parseInt(nodeStyle.zIndex);
1031
1044
  if (nodeStyle.position !== "static" && !isNaN(nodeZIndex)) {
1032
1045
  if (nodeZIndex > zIndex) {
1033
1046
  zIndex = nodeZIndex;
1034
- maxZIndexNode = parent;
1047
+ $maxZIndexNode = $parent;
1035
1048
  }
1036
1049
  }
1037
- parent = parent.parentElement;
1050
+ $parent = $parent.parentElement;
1051
+ }
1052
+ if ($maxZIndexNode) {
1053
+ const maxRect = $maxZIndexNode.getBoundingClientRect();
1054
+ rect = {
1055
+ x: maxRect.x,
1056
+ y: maxRect.y,
1057
+ width: maxRect.width,
1058
+ height: maxRect.height,
1059
+ top: maxRect.top,
1060
+ right: maxRect.right,
1061
+ bottom: maxRect.bottom,
1062
+ left: maxRect.left,
1063
+ };
1038
1064
  }
1039
1065
  return {
1040
- /** 处理了偏移量后的z-index值 */
1066
+ /** 计算偏移量后的z-index值 */
1041
1067
  zIndex: zIndex + deviation,
1042
- /** 原始z-index值 */
1068
+ /** 获取到的最大的z-index值 */
1043
1069
  originZIndex: zIndex,
1044
1070
  /** 拥有最大z-index的元素 */
1045
- node: maxZIndexNode,
1071
+ node: $maxZIndexNode,
1046
1072
  /** 目标坐标元素 */
1047
- positionNode: positionNode,
1048
- /** x坐标 */
1073
+ positionNode: $position,
1074
+ /** 目标x坐标 */
1049
1075
  positionX: positionX,
1050
- /** y坐标 */
1076
+ /** 目标y坐标 */
1051
1077
  positionY: positionY,
1078
+ /** node位置信息 */
1079
+ rect,
1052
1080
  };
1053
1081
  })
1054
1082
  .filter((it) => it != null);
@@ -3788,8 +3816,22 @@ class Utils {
3788
3816
  * 深度获取对象的某个属性
3789
3817
  * @param target 待获取的对象
3790
3818
  * @param handler 获取属性的回调
3819
+ * @example
3820
+ * Utils.queryProperty(window,(target)=>{
3821
+ * if(target.xxx){
3822
+ * return {
3823
+ * isFind: true,
3824
+ * data: target.xxx,
3825
+ * }
3826
+ * }else{
3827
+ * return {
3828
+ * isFind: false,
3829
+ * data: target.aabbcc,
3830
+ * }
3831
+ * }
3832
+ * })
3791
3833
  */
3792
- queryProperty<T = any>(
3834
+ queryProperty<T = any, R = any>(
3793
3835
  target: any,
3794
3836
  handler: (
3795
3837
  /**
@@ -3805,16 +3847,20 @@ class Utils {
3805
3847
  isFind: boolean;
3806
3848
  /**
3807
3849
  * 对象/目标值
3850
+ *
3851
+ * 若`isFind`为true,那该值为返回的结果
3852
+ *
3853
+ * 若`isFind`为false,那该值为下次迭代传入的`target`
3808
3854
  */
3809
- data: any;
3855
+ data: T | R | null | void;
3810
3856
  }
3811
- ): any {
3857
+ ): R | void | null {
3812
3858
  if (target == null) {
3813
3859
  return;
3814
3860
  }
3815
3861
  const handleResult = handler(target);
3816
3862
  if (handleResult && typeof handleResult.isFind === "boolean" && handleResult.isFind) {
3817
- return handleResult.data;
3863
+ return handleResult.data as R | void | null;
3818
3864
  }
3819
3865
  return this.queryProperty(handleResult.data, handler);
3820
3866
  }
@@ -3822,54 +3868,63 @@ class Utils {
3822
3868
  * 异步-深度获取对象属性
3823
3869
  * @param target 待获取的对象
3824
3870
  * @param handler 获取属性的回调
3871
+ * @example
3872
+ * Utils.asyncQueryProperty(window, async (target)=>{
3873
+ * if(target.xxx){
3874
+ * return {
3875
+ * isFind: true,
3876
+ * data: target.xxx,
3877
+ * }
3878
+ * }else{
3879
+ * return {
3880
+ * isFind: false,
3881
+ * data: target.aabbcc,
3882
+ * }
3883
+ * }
3884
+ * })
3825
3885
  */
3826
- async asyncQueryProperty<T = any>(
3886
+ async asyncQueryProperty<T = any, R = any>(
3827
3887
  target: any,
3828
- handler: (target: T) =>
3829
- | {
3830
- /**
3831
- * 是否是需要的属性
3832
- * + true 将目标值赋值给data
3833
- * + false 不是需要的,data为下一个处理的对象
3834
- */
3835
- isFind: boolean;
3836
- /**
3837
- * 对象/目标值
3838
- */
3839
- data: any;
3840
- }
3841
- | Promise<{
3842
- /**
3843
- * 是否是需要的属性
3844
- * + true 将目标值赋值给data
3845
- * + false 不是需要的,data为下一个处理的对象
3846
- */
3847
- isFind: boolean;
3848
- /**
3849
- * 对象/目标值
3850
- */
3851
- data: any;
3852
- }>
3853
- ): Promise<Awaited<T>> {
3888
+ handler: (
3889
+ /**
3890
+ * 该值为返回的data值
3891
+ */
3892
+ target: T
3893
+ ) => IPromise<{
3894
+ /**
3895
+ * 是否是需要的属性
3896
+ * + true 将目标值赋值给data
3897
+ * + false 不是需要的,data为下一个处理的对象
3898
+ */
3899
+ isFind: boolean;
3900
+ /**
3901
+ * 对象/目标值
3902
+ *
3903
+ * 若`isFind`为true,那该值为返回的结果
3904
+ *
3905
+ * 若`isFind`为false,那该值为下次迭代传入的`target`
3906
+ */
3907
+ data: T | R | null | void;
3908
+ }>
3909
+ ): Promise<R | void | null> {
3854
3910
  if (target == null) {
3855
- // @ts-expect-error 空返回
3856
3911
  return;
3857
3912
  }
3858
3913
  const handleResult = await handler(target);
3859
3914
  if (handleResult && typeof handleResult.isFind === "boolean" && handleResult.isFind) {
3860
- return handleResult.data;
3915
+ return handleResult.data as R | void | null;
3861
3916
  }
3862
3917
  return await this.asyncQueryProperty(handleResult.data, handler);
3863
3918
  }
3864
3919
  /**
3865
3920
  * 创建一个新的Utils实例
3866
3921
  * @param option
3867
- * @returns
3922
+ * @example
3923
+ * Utils.createUtils();
3868
3924
  */
3869
3925
  createUtils(option?: WindowApiOption) {
3870
3926
  return new Utils(option);
3871
3927
  }
3872
-
3873
3928
  /**
3874
3929
  * 将对象转换为FormData
3875
3930
  * @param data 待转换的对象
@@ -3935,7 +3990,9 @@ class Utils {
3935
3990
  /**
3936
3991
  * 覆盖对象中的函数this指向
3937
3992
  * @param target 需要覆盖的对象
3938
- * @param [objectThis] 覆盖的this指向,如果为传入,则默认为对象本身
3993
+ * @param objectThis 覆盖的this指向,如果为传入,则默认为对象本身
3994
+ * @example
3995
+ * Utils.coverObjectFunctionThis({})
3939
3996
  */
3940
3997
  coverObjectFunctionThis = CommonUtil.coverObjectFunctionThis.bind(CommonUtil);
3941
3998
  /**
@@ -3986,7 +4043,7 @@ class Utils {
3986
4043
  /**
3987
4044
  * 自动使用 Worker 执行 setTimeout
3988
4045
  * @param callback 回调函数
3989
- * @param [timeout=0] 延迟时间,默认为0
4046
+ * @param timeout 延迟时间,默认为0
3990
4047
  */
3991
4048
  workerSetTimeout(callback: (...args: any[]) => any, timeout: number = 0) {
3992
4049
  try {
@@ -4087,6 +4144,10 @@ class Utils {
4087
4144
  /**
4088
4145
  * 判断页面中是否存在`worker-src`的CSP规则
4089
4146
  * @param timeout 超时时间,默认为`1500ms`
4147
+ * @example
4148
+ * Utils.hasWorkerCSP().then((hasCSP) => {
4149
+ * console.log(hasCSP);
4150
+ * })
4090
4151
  */
4091
4152
  hasWorkerCSP(timeout: number = 1500) {
4092
4153
  return new Promise<boolean>((resolve) => {
@@ -4169,6 +4230,9 @@ class Utils {
4169
4230
  * @param positionY 坐标y信息
4170
4231
  * @param otherPositionX 坐标x信息
4171
4232
  * @param otherPositionY 坐标y信息
4233
+ * @example
4234
+ * Utils.calcPositionDistance(1, 2, 3, 4);
4235
+ * > 2.8284271247461903
4172
4236
  */
4173
4237
  calcPositionDistance(
4174
4238
  positionX: number | string,
@@ -4180,6 +4244,9 @@ class Utils {
4180
4244
  * 计算两个坐标的直线距离
4181
4245
  * @param position 坐标信息
4182
4246
  * @param otherPosition 坐标信息
4247
+ * @example
4248
+ * Utils.calcPositionDistance({x: 1, y: 2}, {x: 3, y: 4});
4249
+ * > 2.8284271247461903
4183
4250
  */
4184
4251
  calcPositionDistance(
4185
4252
  position: { x: number | string; y: number | string },
@@ -9,3 +9,5 @@ declare var msIndexedDB: IDBFactory | null;
9
9
  declare type IPromise<T> = T | Promise<T>;
10
10
 
11
11
  declare type IFunction<T> = T | (() => T);
12
+
13
+ declare type IArray<T> = T | Array<T>;