wsemi 1.9.4 → 1.9.6

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.
Files changed (489) hide show
  1. package/README.md +1 -1
  2. package/dist/wsemi.umd.js +5 -5
  3. package/dist/wsemi.umd.js.map +1 -1
  4. package/docs/-_class.mjs.html +1 -1
  5. package/docs/-_const.mjs.html +1 -1
  6. package/docs/ab2blob.mjs.html +1 -1
  7. package/docs/ab2u8arr.mjs.html +1 -1
  8. package/docs/addExcelWorksheetFromData.mjs.html +1 -1
  9. package/docs/addMonth.mjs.html +1 -1
  10. package/docs/aes2str.mjs.html +1 -1
  11. package/docs/alive.mjs.html +1 -1
  12. package/docs/arr2dt.mjs.html +1 -1
  13. package/docs/arrAccum.mjs.html +1 -1
  14. package/docs/arrAdd.mjs.html +1 -1
  15. package/docs/arrAt.mjs.html +1 -1
  16. package/docs/arrDiff.mjs.html +1 -1
  17. package/docs/arrFilterByKeywords.mjs.html +1 -1
  18. package/docs/arrFilterByNum.mjs.html +1 -1
  19. package/docs/arrFilterByPnum.mjs.html +1 -1
  20. package/docs/arrFilterByPnumAndToLog.mjs.html +1 -1
  21. package/docs/arrFind.mjs.html +1 -1
  22. package/docs/arrGroupByMaxmin.mjs.html +1 -1
  23. package/docs/arrHas.mjs.html +1 -1
  24. package/docs/arrInsert.mjs.html +1 -1
  25. package/docs/arrLookupByMaxmin.mjs.html +1 -1
  26. package/docs/arrMax.mjs.html +1 -1
  27. package/docs/arrMin.mjs.html +1 -1
  28. package/docs/arrMulti.mjs.html +1 -1
  29. package/docs/arrNorm.mjs.html +1 -1
  30. package/docs/arrProduct.mjs.html +1 -1
  31. package/docs/arrPull.mjs.html +1 -1
  32. package/docs/arrPullAt.mjs.html +1 -1
  33. package/docs/arrReduce.mjs.html +1 -1
  34. package/docs/arrReverse.mjs.html +1 -1
  35. package/docs/arrSep.mjs.html +1 -1
  36. package/docs/arrSort.mjs.html +1 -1
  37. package/docs/asind.mjs.html +1 -1
  38. package/docs/atan2d.mjs.html +1 -1
  39. package/docs/atand.mjs.html +1 -1
  40. package/docs/attstr.mjs.html +1 -1
  41. package/docs/b642obj.mjs.html +1 -1
  42. package/docs/b642str.mjs.html +1 -1
  43. package/docs/b642u16arr.mjs.html +1 -1
  44. package/docs/b642u8arr.mjs.html +1 -1
  45. package/docs/binstr.mjs.html +1 -1
  46. package/docs/blob2ab.mjs.html +1 -1
  47. package/docs/blob2b64.mjs.html +1 -1
  48. package/docs/blob2str.mjs.html +1 -1
  49. package/docs/blob2u8arr.mjs.html +1 -1
  50. package/docs/blobs2b64s.mjs.html +1 -1
  51. package/docs/blobs2u8arrs.mjs.html +1 -1
  52. package/docs/bodyLog.mjs.html +1 -1
  53. package/docs/browserView.mjs.html +1 -1
  54. package/docs/browserViewFromBlob.mjs.html +1 -1
  55. package/docs/browserViewFromText.mjs.html +1 -1
  56. package/docs/browserViewFromU8arr.mjs.html +1 -1
  57. package/docs/bs2u8arr.mjs.html +1 -1
  58. package/docs/bufRead.mjs.html +1 -1
  59. package/docs/bufReadDbl.mjs.html +1 -1
  60. package/docs/bufWrite.mjs.html +1 -1
  61. package/docs/bufWriteDbl.mjs.html +1 -1
  62. package/docs/cache.mjs.html +1 -1
  63. package/docs/cacheBd.mjs.html +1 -1
  64. package/docs/cacheSt.mjs.html +1 -1
  65. package/docs/cbol.mjs.html +1 -1
  66. package/docs/cdbl.mjs.html +1 -1
  67. package/docs/ceil.mjs.html +1 -1
  68. package/docs/cfilesize.mjs.html +1 -1
  69. package/docs/cfinancial.mjs.html +1 -1
  70. package/docs/cint.mjs.html +1 -1
  71. package/docs/clearXSS.mjs.html +1 -1
  72. package/docs/clearXSSDyn.mjs.html +1 -1
  73. package/docs/color.mjs.html +1 -1
  74. package/docs/composeToTree.mjs.html +1 -1
  75. package/docs/convertToTree.mjs.html +1 -1
  76. package/docs/copyStrToClipboard.mjs.html +1 -1
  77. package/docs/cosd.mjs.html +1 -1
  78. package/docs/cotd.mjs.html +1 -1
  79. package/docs/createExcelWorkbook.mjs.html +1 -1
  80. package/docs/cscd.mjs.html +1 -1
  81. package/docs/cstr.mjs.html +1 -1
  82. package/docs/day2cht.mjs.html +1 -1
  83. package/docs/debounce.mjs.html +1 -1
  84. package/docs/delay.mjs.html +1 -1
  85. package/docs/dig.mjs.html +1 -1
  86. package/docs/digExp.mjs.html +1 -1
  87. package/docs/domAlert.mjs.html +1 -1
  88. package/docs/domAppend.mjs.html +1 -1
  89. package/docs/domCancelEvent.mjs.html +1 -1
  90. package/docs/domCompareText.mjs.html +1 -1
  91. package/docs/domConvertToPic.mjs.html +1 -1
  92. package/docs/domConvertToPicDyn.mjs.html +1 -1
  93. package/docs/domDetect.mjs.html +341 -205
  94. package/docs/domDrag.mjs.html +1 -1
  95. package/docs/domDragBarAndScroll.mjs.html +1 -1
  96. package/docs/domDragPointer.mjs.html +1 -1
  97. package/docs/domDragPreview.mjs.html +1 -1
  98. package/docs/domDropFiles.mjs.html +1 -1
  99. package/docs/domElementsFromPoint.mjs.html +1 -1
  100. package/docs/domFadeIn.mjs.html +1 -1
  101. package/docs/domFadeOut.mjs.html +1 -1
  102. package/docs/domFind.mjs.html +1 -1
  103. package/docs/domFinds.mjs.html +1 -1
  104. package/docs/domGetAttr.mjs.html +1 -1
  105. package/docs/domGetBoudRect.mjs.html +1 -1
  106. package/docs/domGetBoudRectRefSelf.mjs.html +1 -1
  107. package/docs/domGetFileAccept.mjs.html +1 -1
  108. package/docs/domGetFiles.mjs.html +1 -1
  109. package/docs/domGetParents.mjs.html +1 -1
  110. package/docs/domGetPointFromEvent.mjs.html +1 -1
  111. package/docs/domGetScrollableParent.mjs.html +1 -1
  112. package/docs/domGetWindowSize.mjs.html +1 -1
  113. package/docs/domIsClientXYIn.mjs.html +1 -1
  114. package/docs/domIsFocused.mjs.html +1 -1
  115. package/docs/domIsStable.mjs.html +1 -1
  116. package/docs/domIsVisible.mjs.html +1 -1
  117. package/docs/domPrepend.mjs.html +1 -1
  118. package/docs/domRemove.mjs.html +1 -1
  119. package/docs/domRenderMarkdownMind.mjs.html +1 -1
  120. package/docs/domRenderMarkdownMindDyn.mjs.html +1 -1
  121. package/docs/domRipple.mjs.html +1 -1
  122. package/docs/domScrollIntoView.mjs.html +1 -1
  123. package/docs/domScrollTo.mjs.html +1 -1
  124. package/docs/domSetAttr.mjs.html +1 -1
  125. package/docs/domShowImages.mjs.html +1 -1
  126. package/docs/domShowImagesDyn.mjs.html +1 -1
  127. package/docs/domShowInputAndGetFiles.mjs.html +1 -1
  128. package/docs/domShowInputAndGetFilesU8Arrs.mjs.html +1 -1
  129. package/docs/domShowInputDatatime.mjs.html +1 -1
  130. package/docs/domTooltip.mjs.html +1 -1
  131. package/docs/domTriggerEvent.mjs.html +1 -1
  132. package/docs/domVirtualCreate.mjs.html +1 -1
  133. package/docs/domVirtualCreateQueue.mjs.html +1 -1
  134. package/docs/downloadExcelFileFromData.mjs.html +1 -1
  135. package/docs/downloadExcelFileFromDataDyn.mjs.html +1 -1
  136. package/docs/downloadFileFromB64.mjs.html +1 -1
  137. package/docs/downloadFileFromBlob.mjs.html +1 -1
  138. package/docs/downloadFileFromText.mjs.html +1 -1
  139. package/docs/downloadFileFromU8Arr.mjs.html +1 -1
  140. package/docs/dtmapping.mjs.html +1 -1
  141. package/docs/dtpick.mjs.html +1 -1
  142. package/docs/estimateTicks.mjs.html +1 -1
  143. package/docs/evEmit.mjs.html +1 -1
  144. package/docs/evEmitDelay.mjs.html +1 -1
  145. package/docs/evem.mjs.html +1 -1
  146. package/docs/examples/ex-blob2b64.html +1 -1
  147. package/docs/examples/ex-clearXSS.html +1 -1
  148. package/docs/examples/ex-clearXSSDyn.html +1 -1
  149. package/docs/examples/ex-colorConverter.html +1 -1
  150. package/docs/examples/ex-domCompareText.html +1 -1
  151. package/docs/examples/ex-domConvertToPic.html +1 -1
  152. package/docs/examples/ex-domDrag.html +1 -1
  153. package/docs/examples/ex-domDropFiles.html +1 -1
  154. package/docs/examples/ex-domIsVisible.html +1 -1
  155. package/docs/examples/ex-domRenderMarkdownMind.html +1 -1
  156. package/docs/examples/ex-domRenderMarkdownMindDyn.html +1 -1
  157. package/docs/examples/ex-domRipple.html +1 -1
  158. package/docs/examples/ex-domScrollIntoView.html +1 -1
  159. package/docs/examples/ex-domScrollTo.html +1 -1
  160. package/docs/examples/ex-domShowImages.html +1 -1
  161. package/docs/examples/ex-domShowImagesDyn.html +1 -1
  162. package/docs/examples/ex-domShowInputAndGetFiles.html +1 -1
  163. package/docs/examples/ex-domTooltip.html +1 -1
  164. package/docs/examples/ex-getFileHash.html +1 -1
  165. package/docs/examples/ex-getUserAgent.html +1 -1
  166. package/docs/examples/ex-getUserAgentDyn.html +1 -1
  167. package/docs/examples/ex-html2str.html +1 -1
  168. package/docs/examples/ex-obj2u8arr-u8arr2obj.html +1 -1
  169. package/docs/examples/ex-openLink.html +1 -1
  170. package/docs/examples/ex-str2aes-aes2str.html +1 -1
  171. package/docs/examples/ex-str2b64-b642str.html +1 -1
  172. package/docs/examples/ex-strFindFuzz.html +1 -1
  173. package/docs/examples/ex-timeTZ2expire-timeTZ2past.html +1 -1
  174. package/docs/examples/ex-xlsx.html +1 -1
  175. package/docs/execCli.mjs.html +1 -1
  176. package/docs/execCliCore.mjs.html +1 -1
  177. package/docs/execCliJsonRpc.mjs.html +1 -1
  178. package/docs/execCliSession.mjs.html +1 -1
  179. package/docs/execJsCode.mjs.html +1 -1
  180. package/docs/execProcess.mjs.html +1 -1
  181. package/docs/execProcessKillPid.mjs.html +1 -1
  182. package/docs/filepathToTree.mjs.html +1 -1
  183. package/docs/files2data.mjs.html +1 -1
  184. package/docs/flattenToConn.mjs.html +1 -1
  185. package/docs/flattenTree.mjs.html +1 -1
  186. package/docs/floor.mjs.html +1 -1
  187. package/docs/fsBuildReadStreamText.mjs.html +1 -1
  188. package/docs/fsBuildWriteStreamText.mjs.html +1 -1
  189. package/docs/fsCleanFolder.mjs.html +1 -1
  190. package/docs/fsCleanFolderCore.mjs.html +1 -1
  191. package/docs/fsCopyFile.mjs.html +1 -1
  192. package/docs/fsCopyFileCore.mjs.html +1 -1
  193. package/docs/fsCopyFolder.mjs.html +1 -1
  194. package/docs/fsCopyFolderCore.mjs.html +1 -1
  195. package/docs/fsCreateFile.mjs.html +1 -1
  196. package/docs/fsCreateFileCore.mjs.html +1 -1
  197. package/docs/fsCreateFolder.mjs.html +1 -1
  198. package/docs/fsCreateFolderCore.mjs.html +1 -1
  199. package/docs/fsDeleteFile.mjs.html +1 -1
  200. package/docs/fsDeleteFileCore.mjs.html +1 -1
  201. package/docs/fsDeleteFileSafe.mjs.html +1 -1
  202. package/docs/fsDeleteFileSafeCore.mjs.html +1 -1
  203. package/docs/fsDeleteFolder.mjs.html +1 -1
  204. package/docs/fsDeleteFolderCore.mjs.html +1 -1
  205. package/docs/fsDeleteFolderSafe.mjs.html +1 -1
  206. package/docs/fsDeleteFolderSafeCore.mjs.html +1 -1
  207. package/docs/fsDownloadFile.mjs.html +1 -1
  208. package/docs/fsDownloadFileCore.mjs.html +1 -1
  209. package/docs/fsEvem.mjs.html +1 -1
  210. package/docs/fsExists.mjs.html +1 -1
  211. package/docs/fsExistsCore.mjs.html +1 -1
  212. package/docs/fsGetFileBasicHash.mjs.html +1 -1
  213. package/docs/fsGetFileBasicHashCore.mjs.html +1 -1
  214. package/docs/fsGetFileHash.mjs.html +1 -1
  215. package/docs/fsGetFileHashCore.mjs.html +1 -1
  216. package/docs/fsGetFileXxHash.mjs.html +1 -1
  217. package/docs/fsGetFileXxHashCore.mjs.html +1 -1
  218. package/docs/fsGetFilesInFolder.mjs.html +1 -1
  219. package/docs/fsGetFilesInFolderCore.mjs.html +1 -1
  220. package/docs/fsGetFilesWithHashInFolder.mjs.html +1 -1
  221. package/docs/fsGetFilesWithHashInFolderCore.mjs.html +1 -1
  222. package/docs/fsGetFolderBasicHash.mjs.html +1 -1
  223. package/docs/fsGetFolderBasicHashCore.mjs.html +1 -1
  224. package/docs/fsGetFoldersInFolder.mjs.html +1 -1
  225. package/docs/fsGetFoldersInFolderCore.mjs.html +1 -1
  226. package/docs/fsIsFile.mjs.html +1 -1
  227. package/docs/fsIsFileCore.mjs.html +1 -1
  228. package/docs/fsIsFolder.mjs.html +1 -1
  229. package/docs/fsIsFolderCore.mjs.html +1 -1
  230. package/docs/fsMergeFiles.mjs.html +1 -1
  231. package/docs/fsMergeFilesCore.mjs.html +1 -1
  232. package/docs/fsReadJson.mjs.html +1 -1
  233. package/docs/fsReadText.mjs.html +1 -1
  234. package/docs/fsReadTextCore.mjs.html +1 -1
  235. package/docs/fsRenameFile.mjs.html +1 -1
  236. package/docs/fsRenameFileCore.mjs.html +1 -1
  237. package/docs/fsRenameFolder.mjs.html +1 -1
  238. package/docs/fsRenameFolderCore.mjs.html +1 -1
  239. package/docs/fsSrlog.mjs.html +1 -1
  240. package/docs/fsSyncFolder.mjs.html +1 -1
  241. package/docs/fsSyncFolderCore.mjs.html +1 -1
  242. package/docs/fsTask.mjs.html +1 -1
  243. package/docs/fsTaskCp.mjs.html +1 -1
  244. package/docs/fsTreeFolder.mjs.html +1 -1
  245. package/docs/fsTreeFolderCore.mjs.html +1 -1
  246. package/docs/fsTreeFolderWithHash.mjs.html +1 -1
  247. package/docs/fsTreeFolderWithHashCore.mjs.html +1 -1
  248. package/docs/fsWatchFile.mjs.html +1 -1
  249. package/docs/fsWatchFolder.mjs.html +1 -1
  250. package/docs/fsWriteJson.mjs.html +1 -1
  251. package/docs/fsWriteText.mjs.html +1 -1
  252. package/docs/fsWriteTextCore.mjs.html +1 -1
  253. package/docs/genGradientColor.mjs.html +1 -1
  254. package/docs/genID.mjs.html +1 -1
  255. package/docs/genIDSeq.mjs.html +1 -1
  256. package/docs/genPm.mjs.html +1 -1
  257. package/docs/getBufferSize.mjs.html +1 -1
  258. package/docs/getClearPathName.mjs.html +1 -1
  259. package/docs/getCsvStrFromData.mjs.html +1 -1
  260. package/docs/getDataFromExcelFileU8Arr.mjs.html +1 -1
  261. package/docs/getDataFromExcelFileU8ArrDyn.mjs.html +1 -1
  262. package/docs/getEnv.mjs.html +1 -1
  263. package/docs/getErrorMessage.mjs.html +1 -1
  264. package/docs/getExcelU8ArrFromData.mjs.html +1 -1
  265. package/docs/getExcelU8ArrFromWorkbook.mjs.html +1 -1
  266. package/docs/getExcelWorkbookFromData.mjs.html +1 -1
  267. package/docs/getExcelWorkbookFromWorksheet.mjs.html +1 -1
  268. package/docs/getExcelWorksheetFromData.mjs.html +1 -1
  269. package/docs/getFileAccept.mjs.html +1 -1
  270. package/docs/getFileBasicHash.mjs.html +1 -1
  271. package/docs/getFileHash.mjs.html +1 -1
  272. package/docs/getFileName.mjs.html +1 -1
  273. package/docs/getFileNameExt.mjs.html +1 -1
  274. package/docs/getFileTrueName.mjs.html +1 -1
  275. package/docs/getFileType.mjs.html +1 -1
  276. package/docs/getFileXxHash.mjs.html +1 -1
  277. package/docs/getGlobal.mjs.html +1 -1
  278. package/docs/getObjSize.mjs.html +1 -1
  279. package/docs/getPathParent.mjs.html +1 -1
  280. package/docs/getTimeBetween.mjs.html +1 -1
  281. package/docs/getTimeFromUnit.mjs.html +1 -1
  282. package/docs/getTimeHp.mjs.html +1 -1
  283. package/docs/getTimeObject.mjs.html +1 -1
  284. package/docs/getTimeRange.mjs.html +1 -1
  285. package/docs/getUserAgent.mjs.html +1 -1
  286. package/docs/getUserAgentDyn.mjs.html +1 -1
  287. package/docs/getltdtkeys.mjs.html +1 -1
  288. package/docs/global.html +1 -1
  289. package/docs/haskey.mjs.html +1 -1
  290. package/docs/html2str.mjs.html +1 -1
  291. package/docs/htmlDecode.mjs.html +1 -1
  292. package/docs/htmlEncode.mjs.html +1 -1
  293. package/docs/importResources.mjs.html +1 -1
  294. package/docs/index.html +1 -1
  295. package/docs/interp1.mjs.html +1 -1
  296. package/docs/isDate.mjs.html +1 -1
  297. package/docs/isDev.mjs.html +1 -1
  298. package/docs/isEle.mjs.html +1 -1
  299. package/docs/isEleExistByID.mjs.html +1 -1
  300. package/docs/isEmail.mjs.html +1 -1
  301. package/docs/isErr.mjs.html +1 -1
  302. package/docs/isIE.mjs.html +1 -1
  303. package/docs/isNarrow.mjs.html +1 -1
  304. package/docs/isStrHasCapital.mjs.html +1 -1
  305. package/docs/isStrHasLetter.mjs.html +1 -1
  306. package/docs/isStrHasLowerCase.mjs.html +1 -1
  307. package/docs/isStrHasNumber.mjs.html +1 -1
  308. package/docs/isStrHasSpace.mjs.html +1 -1
  309. package/docs/isStrHasSymbol.mjs.html +1 -1
  310. package/docs/isUserIdentify.mjs.html +1 -1
  311. package/docs/isUserName.mjs.html +1 -1
  312. package/docs/isUserPw.mjs.html +1 -1
  313. package/docs/isWindow.mjs.html +1 -1
  314. package/docs/isab.mjs.html +1 -1
  315. package/docs/isarr.mjs.html +1 -1
  316. package/docs/isarr0.mjs.html +1 -1
  317. package/docs/isarr1.mjs.html +1 -1
  318. package/docs/isbigint.mjs.html +1 -1
  319. package/docs/isblob.mjs.html +1 -1
  320. package/docs/isbol.mjs.html +1 -1
  321. package/docs/isday.mjs.html +1 -1
  322. package/docs/isearr.mjs.html +1 -1
  323. package/docs/iseobj.mjs.html +1 -1
  324. package/docs/iser.mjs.html +1 -1
  325. package/docs/isernot.mjs.html +1 -1
  326. package/docs/isestr.mjs.html +1 -1
  327. package/docs/isfile.mjs.html +1 -1
  328. package/docs/isfun.mjs.html +1 -1
  329. package/docs/isint.mjs.html +1 -1
  330. package/docs/ismonth.mjs.html +1 -1
  331. package/docs/isn0int.mjs.html +1 -1
  332. package/docs/isn0num.mjs.html +1 -1
  333. package/docs/isnan.mjs.html +1 -1
  334. package/docs/isnbr.mjs.html +1 -1
  335. package/docs/isnint.mjs.html +1 -1
  336. package/docs/isnnum.mjs.html +1 -1
  337. package/docs/isnull.mjs.html +1 -1
  338. package/docs/isnum.mjs.html +1 -1
  339. package/docs/isobj.mjs.html +1 -1
  340. package/docs/isobj0.mjs.html +1 -1
  341. package/docs/isp0int.mjs.html +1 -1
  342. package/docs/isp0num.mjs.html +1 -1
  343. package/docs/ispint.mjs.html +1 -1
  344. package/docs/ispm.mjs.html +1 -1
  345. package/docs/ispnum.mjs.html +1 -1
  346. package/docs/isstr.mjs.html +1 -1
  347. package/docs/isstr0.mjs.html +1 -1
  348. package/docs/istime.mjs.html +1 -1
  349. package/docs/istimeTZ.mjs.html +1 -1
  350. package/docs/istimems.mjs.html +1 -1
  351. package/docs/istimemsTZ.mjs.html +1 -1
  352. package/docs/isu16arr.mjs.html +1 -1
  353. package/docs/isu8arr.mjs.html +1 -1
  354. package/docs/isundefined.mjs.html +1 -1
  355. package/docs/j2o.mjs.html +1 -1
  356. package/docs/judge.mjs.html +1 -1
  357. package/docs/keysmat2ltdt.mjs.html +1 -1
  358. package/docs/ltdt2vrtsable.mjs.html +1 -1
  359. package/docs/ltdtDiff.mjs.html +1 -1
  360. package/docs/ltdtDiffByKey.mjs.html +1 -1
  361. package/docs/ltdtkeys2mat.mjs.html +1 -1
  362. package/docs/ltdtkeysheads2mat.mjs.html +1 -1
  363. package/docs/ltdtmapping.mjs.html +1 -1
  364. package/docs/ltdtmerge.mjs.html +1 -1
  365. package/docs/ltdtpick.mjs.html +1 -1
  366. package/docs/ltdtpull.mjs.html +1 -1
  367. package/docs/mat2ltdt.mjs.html +1 -1
  368. package/docs/matConcat.mjs.html +1 -1
  369. package/docs/matDiff.mjs.html +1 -1
  370. package/docs/matat.mjs.html +1 -1
  371. package/docs/now2str.mjs.html +1 -1
  372. package/docs/now2strp.mjs.html +1 -1
  373. package/docs/nowDay2str.mjs.html +1 -1
  374. package/docs/nowms2str.mjs.html +1 -1
  375. package/docs/nowms2strp.mjs.html +1 -1
  376. package/docs/o2j.mjs.html +1 -1
  377. package/docs/obj2b64.mjs.html +1 -1
  378. package/docs/obj2pb64.mjs.html +1 -1
  379. package/docs/obj2str.mjs.html +1 -1
  380. package/docs/obj2stru8arr.mjs.html +1 -1
  381. package/docs/obj2u8arr.mjs.html +1 -1
  382. package/docs/objSortBy.mjs.html +1 -1
  383. package/docs/objSortByKeys.mjs.html +1 -1
  384. package/docs/oo.mjs.html +1 -1
  385. package/docs/openLink.mjs.html +1 -1
  386. package/docs/pb642obj.mjs.html +1 -1
  387. package/docs/pmChain.mjs.html +1 -1
  388. package/docs/pmConvertResolve.mjs.html +1 -1
  389. package/docs/pmDebounce.mjs.html +1 -1
  390. package/docs/pmHook.mjs.html +1 -1
  391. package/docs/pmHookReject.mjs.html +1 -1
  392. package/docs/pmIni.mjs.html +1 -1
  393. package/docs/pmInvResolve.mjs.html +1 -1
  394. package/docs/pmKeyMutex.mjs.html +1 -1
  395. package/docs/pmMap.mjs.html +1 -1
  396. package/docs/pmQueue.mjs.html +1 -1
  397. package/docs/pmSeries.mjs.html +1 -1
  398. package/docs/pmThrottle.mjs.html +1 -1
  399. package/docs/pmTimeout.mjs.html +1 -1
  400. package/docs/preciseNum.mjs.html +1 -1
  401. package/docs/pseudoRandom.mjs.html +1 -1
  402. package/docs/pseudoRandomIntRange.mjs.html +1 -1
  403. package/docs/pseudoRandomIntsNdpRange.mjs.html +1 -1
  404. package/docs/pseudoRandomIntsRange.mjs.html +1 -1
  405. package/docs/pseudoRandomRange.mjs.html +1 -1
  406. package/docs/pseudoRandomsRange.mjs.html +1 -1
  407. package/docs/queue.mjs.html +1 -1
  408. package/docs/random.mjs.html +1 -1
  409. package/docs/randomIntRange.mjs.html +1 -1
  410. package/docs/randomIntsNdpRange.mjs.html +1 -1
  411. package/docs/randomIntsRange.mjs.html +1 -1
  412. package/docs/randomRange.mjs.html +1 -1
  413. package/docs/randomsRange.mjs.html +1 -1
  414. package/docs/rang.mjs.html +1 -1
  415. package/docs/rep.mjs.html +1 -1
  416. package/docs/repObj.mjs.html +1 -1
  417. package/docs/replace.mjs.html +1 -1
  418. package/docs/replaceObj.mjs.html +1 -1
  419. package/docs/replacePlus.mjs.html +1 -1
  420. package/docs/round.mjs.html +1 -1
  421. package/docs/secd.mjs.html +1 -1
  422. package/docs/sep.mjs.html +1 -1
  423. package/docs/sepInt.mjs.html +1 -1
  424. package/docs/setIntervalHp.mjs.html +1 -1
  425. package/docs/setTimeoutHp.mjs.html +1 -1
  426. package/docs/sind.mjs.html +1 -1
  427. package/docs/split.mjs.html +1 -1
  428. package/docs/str2aes.mjs.html +1 -1
  429. package/docs/str2b64.mjs.html +1 -1
  430. package/docs/str2hint.mjs.html +1 -1
  431. package/docs/str2md5.mjs.html +1 -1
  432. package/docs/str2obj.mjs.html +1 -1
  433. package/docs/str2sha.mjs.html +1 -1
  434. package/docs/str2sha512.mjs.html +1 -1
  435. package/docs/str2u8arr.mjs.html +1 -1
  436. package/docs/strCompare.mjs.html +1 -1
  437. package/docs/strCompareForVersion.mjs.html +1 -1
  438. package/docs/strDiff.mjs.html +1 -1
  439. package/docs/strDiffToHtml.mjs.html +1 -1
  440. package/docs/strFindFuzz.mjs.html +1 -1
  441. package/docs/strFindSimilar.mjs.html +1 -1
  442. package/docs/strTruncate.mjs.html +1 -1
  443. package/docs/strdelleft.mjs.html +1 -1
  444. package/docs/strdelright.mjs.html +1 -1
  445. package/docs/strleft.mjs.html +1 -1
  446. package/docs/strmid.mjs.html +1 -1
  447. package/docs/strright.mjs.html +1 -1
  448. package/docs/stru8arr2obj.mjs.html +1 -1
  449. package/docs/tand.mjs.html +1 -1
  450. package/docs/time2day.mjs.html +1 -1
  451. package/docs/time2hour.mjs.html +1 -1
  452. package/docs/time2min.mjs.html +1 -1
  453. package/docs/timeTZ2day.mjs.html +1 -1
  454. package/docs/timeTZ2expire.mjs.html +1 -1
  455. package/docs/timeTZ2hour.mjs.html +1 -1
  456. package/docs/timeTZ2min.mjs.html +1 -1
  457. package/docs/timeTZ2past.mjs.html +1 -1
  458. package/docs/timems2day.mjs.html +1 -1
  459. package/docs/timems2hour.mjs.html +1 -1
  460. package/docs/timems2min.mjs.html +1 -1
  461. package/docs/timems2time.mjs.html +1 -1
  462. package/docs/timemsTZ2day.mjs.html +1 -1
  463. package/docs/timemsTZ2expire.mjs.html +1 -1
  464. package/docs/timemsTZ2hour.mjs.html +1 -1
  465. package/docs/timemsTZ2min.mjs.html +1 -1
  466. package/docs/timemsTZ2past.mjs.html +1 -1
  467. package/docs/timemsTZ2time.mjs.html +1 -1
  468. package/docs/treeObj.mjs.html +1 -1
  469. package/docs/treeToFilepath.mjs.html +1 -1
  470. package/docs/trim.mjs.html +1 -1
  471. package/docs/u16arr2b64.mjs.html +1 -1
  472. package/docs/u16arr2u8arr.mjs.html +1 -1
  473. package/docs/u8arr2ab.mjs.html +1 -1
  474. package/docs/u8arr2b64.mjs.html +1 -1
  475. package/docs/u8arr2blob.mjs.html +1 -1
  476. package/docs/u8arr2bs.mjs.html +1 -1
  477. package/docs/u8arr2obj.mjs.html +1 -1
  478. package/docs/u8arr2str.mjs.html +1 -1
  479. package/docs/u8arr2u16arr.mjs.html +1 -1
  480. package/docs/urlParse.mjs.html +1 -1
  481. package/docs/verifyValue.mjs.html +1 -1
  482. package/docs/waitFun.mjs.html +1 -1
  483. package/docs/wsemi.html +127 -7
  484. package/package.json +1 -1
  485. package/src/domDetect.mjs +340 -204
  486. package/test/domDetect.test.mjs +1248 -11
  487. package/toolfp/dist/wsemip.umd.js +1 -1
  488. package/toolparfor/dist/wpf.umd.js +1 -1
  489. package/toolparfor/dist/wpf_pmSeries.umd.js +1 -1
@@ -46,141 +46,21 @@
46
46
  <section>
47
47
  <article>
48
48
  <pre class="prettyprint source linenums"><code>import get from 'lodash-es/get.js'
49
+ import throttle from 'lodash-es/throttle.js'
49
50
  import ispint from './ispint.mjs'
50
51
  import isp0int from './isp0int.mjs'
52
+ import isnum from './isnum.mjs'
53
+ import cdbl from './cdbl.mjs'
51
54
  import evem from './evem.mjs'
52
55
  import isfun from './isfun.mjs'
53
56
 
54
57
 
55
- //2020年曾以IntersectionObserver與ResizeObserver實作(即下方註解舊碼), 因下列實作缺陷致WTextSelect下拉選單不穩而改為輪詢:
58
+ //2020年曾以IntersectionObserver與ResizeObserver實作(詳細請查git紀錄), 因實作缺陷致WTextSelect下拉選單不穩而改為輪詢:
56
59
  //1.元素尺寸為0(隱藏或移出DOM)時仍發出resize, 使用端讀到高度0而算錯版面
57
60
  //2.clear未防空值, 元素尚未取得即clear時拋錯, 且已建立之觀察器與已排定之事件未解除
58
61
  //3.觀察器只綁首次取得之元素, 元素被換成新節點後即失去偵測
59
- //現以ResizeObserver偵測尺寸, 並以共用MutationObserver於[元素取不到、不在頁面中或尺寸為0]時重新取得元素, 逐一對應上述缺陷; 無ResizeObserver或MutationObserver時退回輪詢
60
62
 
61
-
62
- // function domDetect(f, opt = {}) {
63
-
64
- //使用IntersectionObserver與ResizeObserver時, 當顯隱頻繁導致元素尚未出現需等待與過快清除時, 會導致WTextSelect下拉選單無法穩定出現內容問題
65
-
66
- // let ele = null
67
- // let obInts = null
68
- // let obRes = null
69
-
70
- // //tolerancePixel
71
- // let tolerancePixel = get(opt, 'tolerancePixel', null)
72
- // if (!ispint(tolerancePixel)) {
73
- // tolerancePixel = 1
74
- // }
75
-
76
- // //ev
77
- // let ev = evem()
78
-
79
- // //timer, sold
80
- // let timer
81
- // let sold = {
82
- // offsetWidth: 0,
83
- // offsetHeight: 0,
84
- // }
85
-
86
- // //check
87
- // if (!isfun(f)) {
88
- // console.log('invalid f', f)
89
- // return ev
90
- // }
91
-
92
- // //check
93
- // if (!window.IntersectionObserver) {
94
- // console.log('invalid IntersectionObserver')
95
- // return ev
96
- // }
97
-
98
- // //check
99
- // if (!window.ResizeObserver) {
100
- // console.log('invalid ResizeObserver')
101
- // return ev
102
- // }
103
-
104
- // //setInterval
105
- // timer = setInterval(() => {
106
-
107
- // //execute
108
- // let eleTemp = f()
109
-
110
- // //check
111
- // if (eleTemp) {
112
-
113
- // //save
114
- // ele = eleTemp
115
-
116
- // //obInts
117
- // if (!obInts) {
118
- // obInts = new window.IntersectionObserver((entries) => {
119
- // let entry = entries[0]
120
-
121
- // setTimeout(() => { //emit觸發事件為同步, 用setTimeout脫勾
122
- // ev.emit('display', { mode: entry.isIntersecting ? 'show' : 'hide', ele })
123
- // }, 1)
124
-
125
- // })
126
- // obInts.observe(ele)
127
- // }
128
-
129
- // //obRes
130
- // if (!obRes) {
131
- // obRes = new window.ResizeObserver((entries) => {
132
- // // let entry = entries[0]
133
-
134
- // //new size
135
- // let snew = {
136
- // offsetWidth: ele.offsetWidth,
137
- // offsetHeight: ele.offsetHeight,
138
- // }
139
-
140
- // //save sold
141
- // let soldt = { ...sold }
142
-
143
- // //tolerancePixel
144
- // let bw = Math.abs(sold.offsetWidth - snew.offsetWidth) > tolerancePixel
145
- // let bh = Math.abs(sold.offsetHeight - snew.offsetHeight) > tolerancePixel
146
-
147
- // if (bw || bh) {
148
- // setTimeout(() => { //emit觸發事件為同步, 用setTimeout脫勾
149
- // ev.emit('resize', { sold: soldt, snew, ele })
150
- // ev.emit('resizeWithWindow', { sold: soldt, snew, ele, from: 'dom' })
151
- // }, 1)
152
- // }
153
-
154
- // //save
155
- // sold = snew
156
-
157
- // })
158
- // obRes.observe(ele)
159
- // }
160
-
161
- // //clearInterval
162
- // clearInterval(timer)
163
-
164
- // }
165
-
166
- // }, 10)
167
-
168
- // //fWindowResize
169
- // let fWindowResize = (e) => {
170
- // ev.emit('resizeWithWindow', { snew: sold, from: 'window' })
171
- // }
172
- // window.addEventListener('resize', fWindowResize)
173
-
174
- // //clear
175
- // ev.clear = () => {
176
- // obInts.unobserve(ele)
177
- // obRes.unobserve(ele)
178
- // clearInterval(timer) //若一直沒偵測到元素故也需要強制中止timer
179
- // window.removeEventListener('resize', fWindowResize)
180
- // }
181
-
182
- // return ev
183
- // }
63
+ //現已恢復並用以ResizeObserver偵測尺寸, 並以共用MutationObserver於[元素取不到、不在頁面中或尺寸為0]時重新取得元素, 逐一對應上述缺陷; 無ResizeObserver或MutationObserver時退回輪詢
184
64
 
185
65
 
186
66
  //waiting, 等待重新取得元素之偵測器; mo, 共用之MutationObserver, 僅於有偵測器等待時啟用
@@ -228,6 +108,21 @@ function getTolerancePixel(opt) {
228
108
  }
229
109
 
230
110
 
111
+ function getThrottle(opt) {
112
+ let t = get(opt, 'throttle', null)
113
+ if (!ispint(t)) { //未給或0表示不節流
114
+ t = 0
115
+ }
116
+ return t
117
+ }
118
+
119
+
120
+ function getFun(opt, key) {
121
+ let f = get(opt, key, null)
122
+ return isfun(f) ? f : null
123
+ }
124
+
125
+
231
126
  //getEle, f()拋錯或回傳非元素時視為取不到, 不中斷偵測
232
127
  function getEle(f) {
233
128
  let p = null
@@ -241,6 +136,12 @@ function getEle(f) {
241
136
  }
242
137
 
243
138
 
139
+ //toNum, 非數字(含拋錯、未給)者為null
140
+ function toNum(v) {
141
+ return isnum(v) ? cdbl(v) : null
142
+ }
143
+
144
+
244
145
  function sizeZero() {
245
146
  return {
246
147
  offsetWidth: 0,
@@ -249,26 +150,79 @@ function sizeZero() {
249
150
  clientHeight: 0,
250
151
  windowWidth: 0,
251
152
  windowHeight: 0,
153
+ width: 0,
154
+ height: 0,
252
155
  }
253
156
  }
254
157
 
255
158
 
256
- function measure(p) {
257
- return {
159
+ //measure, width與height為比較用尺寸: 預設同offsetWidth與offsetHeight(border-box), 有給getSize時取其回傳(例如使用端依內容區繪製者)
160
+ function measure(p, getSize) {
161
+ let r = {
258
162
  offsetWidth: p.offsetWidth,
259
163
  offsetHeight: p.offsetHeight,
260
164
  clientWidth: p.clientWidth,
261
165
  clientHeight: p.clientHeight,
262
166
  windowWidth: window.innerWidth,
263
167
  windowHeight: window.innerHeight,
168
+ width: p.offsetWidth,
169
+ height: p.offsetHeight,
264
170
  }
171
+ if (getSize) {
172
+ let s = null
173
+ try {
174
+ s = getSize(p)
175
+ }
176
+ catch (err) {
177
+ s = null
178
+ }
179
+ r.width = toNum(get(s, 'width', null)) || 0
180
+ r.height = toNum(get(s, 'height', null)) || 0
181
+ }
182
+ return r
183
+ }
184
+
185
+
186
+ //isShown, 量測時元素可見(外框非0)且比較用尺寸非0
187
+ function isShown(s) {
188
+ return s.offsetWidth > 0 &amp;&amp; s.offsetHeight > 0 &amp;&amp; s.width > 0 &amp;&amp; s.height > 0
189
+ }
190
+
191
+
192
+ //isRendered, 元素當下是否被繪製: 在頁面中且自身與祖先皆非display:none
193
+ // 只需計算樣式不需排版: 若讀外框(offsetWidth)確認, 前一個監聽器改動DOM後(同步寫入或Vue於microtask更新)之每次確認皆強制重排, N個偵測器即N次排版
194
+ // 有checkVisibility時以其判定(另涵蓋content-visibility:hidden等), 否則逐層檢查display; 不讀外框, 故元素仍被繪製而尺寸縮為0者視為被繪製
195
+ function isRendered(p) {
196
+ if (!p || !p.isConnected) {
197
+ return false
198
+ }
199
+ if (isfun(p.checkVisibility)) {
200
+ return p.checkVisibility()
201
+ }
202
+ let e = p
203
+ while (e &amp;&amp; e.nodeType === 1) {
204
+ let display = ''
205
+ try {
206
+ display = window.getComputedStyle(e).display
207
+ }
208
+ catch (err) {
209
+ display = ''
210
+ }
211
+ if (display === 'none') {
212
+ return false
213
+ }
214
+ e = e.parentElement || (e.parentNode &amp;&amp; e.parentNode.host) || null //Shadow DOM內之頂層節點改查其宿主
215
+ }
216
+ return true
265
217
  }
266
218
 
267
219
 
268
220
  //createCore, 輪詢與ResizeObserver兩種模式共用之比較、發出、視窗事件與清除, 使兩者之規則只寫一處
269
- // 比較基準sb為上次發出事件時之尺寸, 差值超過容許誤差才更新; 若每次量測皆更新基準, 緩慢之連續小變化(如逐px拖曳或縮放視窗)永遠不會超過容許誤差, 累積再大也不發出
221
+ // 比較基準預設為上次判定變化時之尺寸sb, 差值超過容許誤差才更新; 若每次量測皆更新基準, 緩慢之連續小變化(如逐px拖曳或縮放視窗)永遠不會超過容許誤差, 累積再大也不發出
270
222
  // 尺寸為0時差值必超過容許誤差而使基準歸0, 故由隱藏恢復顯示時必發出
271
- function createCore(ev, opt) {
223
+ // 有給getBase時比較基準改為使用端目前套用之尺寸(例如圖表目前寬高), 故掛載時尺寸已一致者不發出, 且與偵測器之回報次序無關
224
+ // onReobserve為延後發出因元素已不被繪製而略過時, 請觀察層重新觀察目前元素並登記等待之函數(輪詢模式不需要, 下一次取樣即重新比較)
225
+ function createCore(ev, opt, onReobserve) {
272
226
 
273
227
  //tolerancePixel
274
228
  let tolerancePixel = getTolerancePixel(opt)
@@ -276,101 +230,221 @@ function createCore(ev, opt) {
276
230
  //sync, 於ResizeObserver回呼內同步發出事件(繪製前), 供須於同一幀更新版面之使用端(例如圖表重繪); 預設以setTimeout脫勾
277
231
  let sync = get(opt, 'sync', false) === true
278
232
 
279
- //cleared, st, sd, sb, smode, timers
233
+ //getSize, getBase, throttleTime
234
+ let getSize = getFun(opt, 'getSize')
235
+ let getBase = getFun(opt, 'getBase')
236
+ let throttleTime = getThrottle(opt)
237
+
238
+ //cleared, sd, sb, pLast, timers, seqCheck, seqPost
280
239
  let cleared = false
281
- let st = sizeZero() //前次量測
282
240
  let sd = sizeZero() //最新量測
283
- let sb = sizeZero() //比較基準, 上次發出事件時之尺寸
284
- let smode = {
285
- width: '',
286
- height: '',
287
- }
241
+ let sb = sizeZero() //上次判定變化時之尺寸
242
+ let pLast = null //最新量測之元素, 供視窗事件確認其當下是否被繪製
288
243
  let timers = new Set()
244
+ let seqCheck = 0 //判定變化之序號
245
+ let seqPost = 0 //已處理(發出, 或因尺寸0、不被繪製、使用端已同步而不發出)之最新序號
246
+
247
+ //readBase, 比較基準: 有給getBase時取其回傳(該軸非數字表示該軸不比較, 例如固定寬度), 否則為sb
248
+ // pending為判定變化時: 有給getBase且尚有未處理之延後發出者, 使用端尺寸將被其更新, 故比較之軸改以其量測(sb)比較;
249
+ // 否則之後量得與使用端當下相近之尺寸會被判為未變化, 待延後發出套用後使用端即停在過期尺寸; 發出前之再比較(pending為false)則以使用端當下之尺寸比較
250
+ let readBase = (pending) => {
251
+ if (!getBase) {
252
+ return {
253
+ width: sb.width,
254
+ height: sb.height,
255
+ }
256
+ }
257
+ let b = null
258
+ try {
259
+ b = getBase()
260
+ }
261
+ catch (err) {
262
+ b = null
263
+ }
264
+ let width = toNum(get(b, 'width', null))
265
+ let height = toNum(get(b, 'height', null))
266
+ if (pending &amp;&amp; seqPost &lt; seqCheck) {
267
+ return {
268
+ width: width === null ? null : sb.width,
269
+ height: height === null ? null : sb.height,
270
+ }
271
+ }
272
+ return {
273
+ width,
274
+ height,
275
+ }
276
+ }
277
+
278
+ //diff, 各軸相對比較基準之差與是否超過容許誤差
279
+ let diff = (snew, pending) => {
280
+ let base = readBase(pending)
281
+ let dw = base.width === null ? 0 : base.width - snew.width
282
+ let dh = base.height === null ? 0 : base.height - snew.height
283
+ return {
284
+ dw,
285
+ dh,
286
+ bw: Math.abs(dw) > tolerancePixel,
287
+ bh: Math.abs(dh) > tolerancePixel,
288
+ }
289
+ }
290
+
291
+ //mode, 方向只於該軸超過容許誤差時給: 容許誤差內之差值視同未變化(不發事件), 若仍給方向, 另一軸觸發之事件會帶出該軸之殘餘方向
292
+ let mode = (d) => {
293
+ return {
294
+ width: d.bw ? (d.dw > 0 ? 'smaller' : 'larger') : '',
295
+ height: d.bh ? (d.dh > 0 ? 'smaller' : 'larger') : '',
296
+ }
297
+ }
289
298
 
290
- //emit
291
- let emit = (sold, snew, sm, p) => {
299
+ //skip, 延後發出前元素已不被繪製而不發出:
300
+ // 若此為最近一次判定之變化(之後未再判定), 比較基準與最新量測歸0, 並請觀察層重新觀察目前元素; 否則元素於下一幀前恢復顯示且尺寸與隱藏前相同時ResizeObserver不再回報(上次回報之尺寸未變), 此次變化即永不發出
301
+ // 之後已再判定變化者由該次發出處理, 不得歸0, 否則覆蓋較新之比較基準
302
+ let skip = (snew) => {
303
+ if (sb !== snew) {
304
+ return
305
+ }
306
+ sb = sizeZero()
307
+ sd = sizeZero()
308
+ if (onReobserve) {
309
+ onReobserve()
310
+ }
311
+ }
312
+
313
+ //post, 發出事件
314
+ // deferred為延後發出(setTimeout、節流之後續呼叫或refresh): 自量測至發出之間元素可能已隱藏或移出頁面, 若照發則使用端讀到尺寸0而算錯版面(即上方2020年缺陷1), 故發出前確認元素當下仍被繪製;
315
+ // 有給getBase者亦再比較一次, 期間使用端已自行同步尺寸時不發出, 方向亦依當下比較重給
316
+ let post = (sold, snew, sm, p, seq, deferred) => {
292
317
 
293
318
  //cleared, clear後不再發出已排定之事件
294
319
  if (cleared) {
295
320
  return
296
321
  }
297
322
 
298
- //detect resize, 尺寸為0(隱藏或移出DOM)不發出
299
- if (snew.offsetWidth > 0 &amp;&amp; snew.offsetHeight > 0) {
300
- ev.emit('resize', {
301
- sold,
302
- snew,
303
- smode: sm,
304
- ele: p,
305
- })
323
+ //seq, 已處理較新之量測者不發出較舊者: sync時refresh或節流之後續發出為延後發出, 可能晚於其後已同步發出之事件, 照發則使用端最後收到過期尺寸
324
+ if (seq &lt; seqPost) {
325
+ return
326
+ }
327
+ seqPost = seq
306
328
 
307
- //cleared, resize之監聽器內可能呼叫clear
308
- if (cleared) {
329
+ //尺寸為0(隱藏或移出DOM)不發出
330
+ if (!isShown(snew)) {
331
+ return
332
+ }
333
+
334
+ //deferred
335
+ if (deferred) {
336
+ if (!isRendered(p)) {
337
+ skip(snew)
309
338
  return
310
339
  }
340
+ if (getBase) {
341
+ let d = diff(snew, false)
342
+ if (!d.bw &amp;&amp; !d.bh) {
343
+ return
344
+ }
345
+ sm = mode(d)
346
+ }
347
+ }
348
+
349
+ ev.emit('resize', {
350
+ sold,
351
+ snew,
352
+ smode: sm,
353
+ ele: p,
354
+ })
311
355
 
312
- ev.emit('resizeWithWindow', {
313
- sold,
314
- snew,
315
- smode: sm,
316
- ele: p,
317
- from: 'dom',
318
- })
356
+ //cleared, resize之監聽器內可能呼叫clear
357
+ if (cleared) {
358
+ return
319
359
  }
320
360
 
361
+ ev.emit('resizeWithWindow', {
362
+ sold,
363
+ snew,
364
+ smode: sm,
365
+ ele: p,
366
+ from: 'dom',
367
+ })
368
+
321
369
  }
322
370
 
323
- //check, 量測並與比較基準比較
324
- let check = (p, allowSync) => {
325
- if (cleared || !p) {
371
+ //fire, 於ResizeObserver回呼內同步發出(inSync)或延後發出
372
+ // 延後發出各自一個task: 前一個監聽器於microtask之DOM異動(如Vue之非同步更新)於下一個發出前已套用, 且監聽器不集中於同一個task; 發出前之確認只需樣式(isRendered), 故不因此強制重排
373
+ let inSync = false
374
+ let fire = (sold, snew, sm, p, seq) => {
375
+ if (inSync) {
376
+ post(sold, snew, sm, p, seq, false)
326
377
  return
327
378
  }
379
+ let t = setTimeout(() => { //emit觸發事件為同步, 用setTimeout脫勾
380
+ timers.delete(t)
381
+ post(sold, snew, sm, p, seq, true)
382
+ }, 1)
383
+ timers.add(t)
384
+ }
328
385
 
329
- //new size
330
- let snew = measure(p)
386
+ //fireThrottled, 節流: 首次立即(同步或延後), 其後throttleTime內至多一次並以最後一次之量測延後發出
387
+ let fireThrottled = null
388
+ if (throttleTime > 0) {
389
+ fireThrottled = throttle(fire, throttleTime)
390
+ }
331
391
 
332
- //dw, dh
333
- let dw = sb.offsetWidth - snew.offsetWidth
334
- let dh = sb.offsetHeight - snew.offsetHeight
392
+ //deliver, now為於ResizeObserver回呼內同步發出
393
+ let deliver = (sold, snew, sm, p, seq, now) => {
394
+ inSync = now
395
+ try {
396
+ if (fireThrottled) {
397
+ fireThrottled(sold, snew, sm, p, seq)
398
+ }
399
+ else {
400
+ fire(sold, snew, sm, p, seq)
401
+ }
402
+ }
403
+ finally {
404
+ inSync = false
405
+ }
406
+ }
335
407
 
336
- //bw, bh
337
- let bw = Math.abs(dw) > tolerancePixel
338
- let bh = Math.abs(dh) > tolerancePixel
408
+ //check, 量測並與比較基準比較
409
+ let check = (p, allowSync) => {
410
+ if (cleared) {
411
+ return
412
+ }
339
413
 
340
- //smode
341
- smode = {
342
- width: dw > 0 ? 'smaller' : (dw &lt; 0 ? 'larger' : ''),
343
- height: dh > 0 ? 'smaller' : (dh &lt; 0 ? 'larger' : ''),
414
+ //取不到元素: 最新量測歸0, 視窗事件不發出(同移出頁面); 比較基準不動, 同尺寸之元素再出現時與既有行為相同不發出dom事件
415
+ if (!p) {
416
+ sd = sizeZero()
417
+ pLast = null
418
+ return
344
419
  }
345
420
 
421
+ //new size
422
+ let snew = measure(p, getSize)
423
+
346
424
  //save
347
- st = sd
348
425
  sd = snew
426
+ pLast = p
349
427
 
350
- //check
351
- if (!bw &amp;&amp; !bh) {
428
+ //diff
429
+ let d = diff(snew, true)
430
+ if (!d.bw &amp;&amp; !d.bh) {
352
431
  return
353
432
  }
354
433
 
355
434
  //sold, sb
356
435
  let sold = sb
357
436
  sb = snew
358
- let sm = { ...smode }
359
437
 
360
- //emit
361
- if (allowSync &amp;&amp; sync) {
362
- emit(sold, snew, sm, p)
363
- return
364
- }
365
- let t = setTimeout(() => { //emit觸發事件為同步, 用setTimeout脫勾
366
- timers.delete(t)
367
- emit(sold, snew, sm, p)
368
- }, 1)
369
- timers.add(t)
438
+ //deliver
439
+ seqCheck++
440
+ deliver(sold, snew, mode(d), p, seqCheck, allowSync &amp;&amp; sync)
370
441
 
371
442
  }
372
443
 
373
444
  //fWindowResize, 視窗尺寸取當下值, 否則元素尺寸未變時會一直帶著上次量測時之視窗尺寸
445
+ // sold為比較基準, 與dom事件同義; 任何超過容許誤差之變化皆已立即更新比較基準, 故最新量測與比較基準之差必在容許誤差內, 方向恆為空
446
+ // 元素隱藏、移出頁面、取不到或尚未量得尺寸(最新量測為0)時不發出, 與dom事件之規則一致, 否則使用端於視窗改變時讀到尺寸0而算錯版面
447
+ // 視窗事件於同一幀之ResizeObserver回報前派發, 視窗改變本身使元素隱藏時(如媒體查詢)最新量測仍為隱藏前之尺寸, 故另確認元素當下仍被繪製(只需樣式, 不強制重排)
374
448
  let fWindowResize = (e) => {
375
449
  if (cleared) {
376
450
  return
@@ -380,10 +454,16 @@ function createCore(ev, opt) {
380
454
  windowWidth: window.innerWidth,
381
455
  windowHeight: window.innerHeight,
382
456
  }
457
+ if (!isShown(sd) || !isRendered(pLast)) {
458
+ return
459
+ }
383
460
  ev.emit('resizeWithWindow', {
384
- sold: st,
461
+ sold: sb,
385
462
  snew: sd,
386
- smode,
463
+ smode: {
464
+ width: '',
465
+ height: '',
466
+ },
387
467
  from: 'window',
388
468
  })
389
469
  }
@@ -396,7 +476,11 @@ function createCore(ev, opt) {
396
476
  clearTimeout(t)
397
477
  }
398
478
  timers.clear()
479
+ if (fireThrottled) {
480
+ fireThrottled.cancel()
481
+ }
399
482
  window.removeEventListener('resize', fWindowResize)
483
+ pLast = null
400
484
  }
401
485
 
402
486
  return {
@@ -420,14 +504,19 @@ function domDetectByPolling(f, opt = {}) {
420
504
  let ev = evem()
421
505
  let core = createCore(ev, opt)
422
506
 
423
- //setInterval
507
+ //setInterval, 取不到元素時亦交check處理(最新量測歸0)
424
508
  let timer = setInterval(() => {
425
- let p = getEle(f)
426
- if (p) {
427
- core.check(p, false)
428
- }
509
+ core.check(getEle(f), false)
429
510
  }, getTimeInterval(opt))
430
511
 
512
+ //refresh, 立即重新取得元素並比較(延後發出); clear後不再呼叫f, 同ResizeObserver模式
513
+ ev.refresh = () => {
514
+ if (core.isCleared()) {
515
+ return
516
+ }
517
+ core.check(getEle(f), false)
518
+ }
519
+
431
520
  //clear
432
521
  ev.clear = () => {
433
522
  clearInterval(timer)
@@ -453,26 +542,58 @@ function domDetectByObserver(f, opt = {}) {
453
542
  let timeInterval = getTimeInterval(opt)
454
543
 
455
544
  //ev, core
545
+ // 延後發出略過時重新觀察目前元素, 並依[尺寸為0時等待DOM變動]登記等待(最新量測已歸0), 不依賴重新觀察之首次回報(舊版Safari對0尺寸之新觀察不回報)
456
546
  let ev = evem()
457
- let core = createCore(ev, opt)
547
+ let core = createCore(ev, opt, () => {
548
+ reobserve()
549
+ updateWaiting()
550
+ })
458
551
 
459
- //ele, timerInline, roBorder, roContent
552
+ //ele, timerInline, inlineConn, eleInline, roBorder, roContent
460
553
  let ele = null
461
554
  let timerInline = null
555
+ let inlineConn = false //上次判定是否為行內時元素是否在頁面中
556
+ let eleInline = false //目前元素是否曾判定為行內, 換成新節點時歸零
462
557
  let roBorder = null
463
558
  let roContent = null
464
559
 
560
+ //observe, 同時觀察border-box與content-box: 比較用之offsetWidth即border-box, 只觀察content-box會漏掉只改padding或border之變化; content-box則使捲軸出現或消失時clientWidth保持最新, 且getSize依內容區量測時只改padding之變化亦會回報
561
+ let observe = () => {
562
+ roBorder.observe(ele, { box: 'border-box' })
563
+ roContent.observe(ele)
564
+ }
565
+
566
+ //reobserve, 重新觀察目前元素: 新建之觀察於下一幀回報一次, 供延後發出被略過後重新比較
567
+ // 須先unobserve: 瀏覽器對已以同一盒觀察之元素再observe直接返回, 不重建觀察(Chromium實測)
568
+ let reobserve = () => {
569
+ if (core.isCleared() || !ele) {
570
+ return
571
+ }
572
+ roBorder.unobserve(ele)
573
+ roContent.unobserve(ele)
574
+ observe()
575
+ }
576
+
465
577
  //syncInline, 非替換之行內元素ResizeObserver不回報(規範明定), 取得之元素為display:inline時改以定期量測, 不為inline時停止
578
+ // 元素自身隱藏(display:none, 如v-show)時看不出顯示後之型別: 曾判定為行內者持續定期量測, 否則顯示時ResizeObserver會回報; 不在頁面中時display為空字串, 停止量測, 待插入頁面時(onDomChange)重判
466
579
  let syncInline = () => {
467
- let inline = false
580
+ let display = ''
468
581
  if (ele) {
469
582
  try {
470
- inline = window.getComputedStyle(ele).display === 'inline'
583
+ display = window.getComputedStyle(ele).display
471
584
  }
472
585
  catch (err) {
473
- inline = false
586
+ display = ''
474
587
  }
475
588
  }
589
+ inlineConn = !!(ele &amp;&amp; ele.isConnected)
590
+ if (display === 'inline') {
591
+ eleInline = true
592
+ }
593
+ else if (display !== 'none' &amp;&amp; display !== '') {
594
+ eleInline = false
595
+ }
596
+ let inline = display === 'inline' || (display === 'none' &amp;&amp; eleInline)
476
597
  if (inline &amp;&amp; timerInline === null) {
477
598
  timerInline = setInterval(onResize, timeInterval)
478
599
  }
@@ -483,7 +604,6 @@ function domDetectByObserver(f, opt = {}) {
483
604
  }
484
605
 
485
606
  //retarget, 重新取得元素: 換成新節點時改觀察新節點, 新節點之首次回報由check比較
486
- // 同時觀察border-box與content-box: 比較用之offsetWidth即border-box, 只觀察content-box會漏掉只改padding或border之變化; content-box則使捲軸出現或消失時clientWidth保持最新
487
607
  let retarget = () => {
488
608
  if (core.isCleared()) {
489
609
  return
@@ -497,9 +617,9 @@ function domDetectByObserver(f, opt = {}) {
497
617
  roContent.unobserve(ele)
498
618
  }
499
619
  ele = p
620
+ eleInline = false
500
621
  if (ele) {
501
- roBorder.observe(ele, { box: 'border-box' })
502
- roContent.observe(ele)
622
+ observe()
503
623
  }
504
624
  syncInline()
505
625
  }
@@ -520,8 +640,13 @@ function domDetectByObserver(f, opt = {}) {
520
640
  }
521
641
 
522
642
  //onDomChange, 僅重新取得元素不量測, 避免強制重排版; 換新節點後由ResizeObserver之首次回報觸發check
643
+ // 元素插入或移出頁面時重判是否為行內: 不在頁面中之元素取不到display而判為非行內(如Vue指令之bind時元素尚未插入, 或行內元素移出後定期量測已停止), 行內元素ResizeObserver又不回報, 不於插入後重判則永不量測
644
+ // 僅於在頁面與否改變時重判, 等待中之其他DOM變動不重複讀取樣式
523
645
  let onDomChange = () => {
524
646
  retarget()
647
+ if (ele &amp;&amp; ele.isConnected !== inlineConn) {
648
+ syncInline()
649
+ }
525
650
  updateWaiting()
526
651
  }
527
652
 
@@ -546,6 +671,14 @@ function domDetectByObserver(f, opt = {}) {
546
671
  retarget()
547
672
  updateWaiting()
548
673
 
674
+ //refresh, 立即重新取得元素並比較(延後發出), 供比較基準因尺寸以外之原因改變時使用(例如getBase之固定寬度被取消)
675
+ ev.refresh = () => {
676
+ retarget()
677
+ core.check(ele, false)
678
+ syncInline()
679
+ updateWaiting()
680
+ }
681
+
549
682
  //clear, 可於任何時點呼叫(含元素尚未取得), 並取消已排定之事件
550
683
  ev.clear = () => {
551
684
  if (core.isCleared()) {
@@ -569,13 +702,13 @@ function domDetectByObserver(f, opt = {}) {
569
702
  /**
570
703
  * 前端針對DOM元素監聽resize、resizeWithWindow事件,其中resizeWithWindow為dom resize與window resize皆會觸發的事件
571
704
  *
572
- * 瀏覽器支援ResizeObserver與MutationObserver時以其偵測(即時且閒置時不耗資源),否則退回定期輪詢,兩者之比較規則與事件相同:以offsetWidth、offsetHeight與比較基準之差超過容許誤差即發出,比較基準為上次發出事件時之尺寸,故緩慢之連續小變化累積超過容許誤差亦會發出;尺寸為0(隱藏或移出DOM)不發出,由隱藏恢復顯示時會發出,首次取得非0尺寸時會發出
705
+ * 瀏覽器支援ResizeObserver與MutationObserver時以其偵測(即時且閒置時不耗資源),否則退回定期輪詢,兩者之比較規則與事件相同:以比較用尺寸(預設offsetWidth、offsetHeight)與比較基準之差超過容許誤差即發出,比較基準預設為上次發出事件時之尺寸,故緩慢之連續小變化累積超過容許誤差亦會發出;尺寸為0(隱藏或移出DOM)不發出,由隱藏恢復顯示時會發出,首次取得非0尺寸時會發出;延後發出(非同步、節流或refresh)時,發出前元素已不被繪製(移出頁面,或自身或祖先為display:none)者不發出,待其再顯示時重新比較(同由隱藏恢復顯示,sold為0、smode兩軸為'larger'),此確認只計算樣式而不讀外框,故元素仍被繪製而尺寸於空檔內縮為0者照發;sync為true時refresh與節流之後續發出仍為延後發出,其量測早於已處理之事件者不發出
573
706
  *
574
- * 元素可取不到、中途消失或重建為新節點:取不到、不在頁面中或尺寸為0時,於DOM變動時重新以f取得元素並改觀察之。行內元素(display:inline)ResizeObserver不回報,該偵測器改以定期量測
707
+ * 元素可取不到、中途消失或重建為新節點:取不到、不在頁面中或尺寸為0時,於DOM變動時重新以f取得元素並改觀察之。行內元素(display:inline)ResizeObserver不回報,該偵測器改以定期量測,元素自身隱藏(display:none,如v-show)期間亦持續,顯示後即可量得;是否為行內於取得元素、ResizeObserver回報、定期量測及元素插入或移出頁面時判定
575
708
  *
576
- * 事件內容:sold為比較基準(上次發出事件時之尺寸),snew為本次量測,smode為寬與高相對比較基準之變化方向('larger'、'smaller'或''),ele為元素;from為'window'之事件其snew為最新量測,其中視窗尺寸取事件當下之值
709
+ * 事件內容:sold為上次判定變化時之量測,snew為本次量測(另含width、height為比較用尺寸),smode為寬與高相對比較基準之變化方向('larger'、'smaller'或''),僅該軸之差超過容許誤差時給方向,否則為'',有給getBase者延後發出時依發出當下與使用端尺寸之比較重給,ele為元素;from為'window'之事件無ele,其snew為最新量測,其中視窗尺寸取事件當下之值,其smode寬與高恆為''(視窗事件不代表元素尺寸變化,且最新量測與比較基準之差必在容許誤差內);視窗事件於最新量測之任一維為0(隱藏、移出頁面、取不到元素、尚未量得尺寸,或寬高其一為0之元素),或元素當下不被繪製(例如媒體查詢隨視窗改變而隱藏)時不發出,與dom事件之規則一致
577
710
  *
578
- * 已知限制:ResizeObserver模式下,僅屬性變化(如class)使f改指他元素、或Shadow DOM內之節點被替換時不會跟隨,此類使用端請用mode:'polling';sync為true時監聽器不得使所監聽元素之尺寸於同一幀內再變,否則瀏覽器回報ResizeObserver loop錯誤;Safari 15.4以前不支援觀察border-box,只改padding或border之變化於該處不會發出
711
+ * 已知限制:ResizeObserver模式下,僅屬性變化(如class)使f改指他元素、或Shadow DOM內之節點被替換時不會跟隨,行內元素自取得起即自身為display:none(未曾以行內顯示過)、之後僅以style或class改為顯示者不會開始量測,此類使用端請用mode:'polling';sync為true時監聽器不得使所監聽元素之尺寸於同一幀內再變,否則瀏覽器回報ResizeObserver loop錯誤;Safari 15.4以前不支援觀察border-box,只改padding或border之變化於該處不會發出
579
712
  *
580
713
  * Unit Test: {@link https://github.com/yuda-lyu/wsemi/blob/master/test/domDetect.test.mjs Github}
581
714
  * @memberOf wsemi
@@ -586,7 +719,10 @@ function domDetectByObserver(f, opt = {}) {
586
719
  * @param {Integer} [opt.tolerancePixel=1] 輸入容許誤差整數,單位px,可給0表示任何變化皆發出,預設1
587
720
  * @param {Boolean} [opt.sync=false] 輸入是否於ResizeObserver回呼內同步發出事件布林值,true時使用端可於瀏覽器繪製前更新版面(例如圖表重繪),僅ResizeObserver模式有效,預設false
588
721
  * @param {Boolean} [opt.watchIdentity=false] 輸入元素可見時是否仍於DOM變動時重新取得元素布林值,f可能於舊元素仍可見時改回傳另一元素者給true,僅ResizeObserver模式有效,預設false
589
- * @returns {Object} 回傳物件,可使用on與clear函數,on可監聽resize與resizeWithWindow事件,clear為釋放監聽,可於任何時點呼叫(含元素尚未取得),並取消已排定之事件
722
+ * @param {Function} [opt.getSize=null] 輸入比較用尺寸函數,傳入元素,回傳{width,height},供依內容區或特定量測方式繪製之使用端(例如圖表依clientWidth扣除padding),給予時只改padding、元素內出現或消失捲軸等外框不變之變化亦會發出,回傳非數字或拋錯之軸視為0(不發出),預設null表示使用offsetWidth、offsetHeight
723
+ * @param {Function} [opt.getBase=null] 輸入比較基準函數,回傳使用端目前套用之尺寸{width,height},該軸非數字(含拋錯)表示該軸不比較(例如固定寬度),給予時以其取代上次發出事件時之尺寸,故掛載時尺寸已一致者不發出(其後事件之sold於首次判定變化前為0),由隱藏恢復顯示時若與使用端尺寸相同亦不發出;使用端須於事件內套用新尺寸(getBase之回傳隨之更新),否則之後每次回報皆判定為變化而發出,預設null
724
+ * @param {Integer} [opt.throttle=0] 輸入節流時間整數,單位毫秒,首次立即發出,其後每throttle毫秒至多發出一次並以最後一次之量測發出(其sold為最後一次判定變化前之量測,可能未曾發出),clear時取消待發出者,僅作用於元素尺寸之事件(resize與from為'dom'之resizeWithWindow),視窗事件不節流,預設0表示不節流
725
+ * @returns {Object} 回傳物件,可使用on、refresh與clear函數,on可監聽resize與resizeWithWindow事件,refresh為立即重新量測並比較(延後發出,給throttle時併入節流而至多延後throttle毫秒),供比較基準因尺寸以外之原因改變時使用,clear為釋放監聽,可於任何時點呼叫(含元素尚未取得),並取消已排定之事件
590
726
  * @example
591
727
  * need test in browser
592
728
  *
@@ -629,7 +765,7 @@ export default domDetect
629
765
  <br class="clear">
630
766
 
631
767
  <footer>
632
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Sep 25 2026 14:59:11 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
768
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Sep 26 2026 22:05:36 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
633
769
  </footer>
634
770
 
635
771
  <script>prettyPrint();</script>