DOMUtils

使用js重新对jQuery的部分函数进行了仿写

当前为 2024-05-26 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/465772/1383309/DOMUtils.js

  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  3. typeof define === 'function' && define.amd ? define(factory) :
  4. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.DOMUtils = factory());
  5. })(this, (function () { 'use strict';
  6.  
  7. const DOMUtilsCoreDefaultEnv = {
  8. document: document,
  9. window: window,
  10. globalThis: globalThis,
  11. self: self,
  12. };
  13. const DOMUtilsCoreEnv = {
  14. document: document,
  15. window: window,
  16. globalThis: globalThis,
  17. self: self,
  18. };
  19. const DOMUtilsCore = {
  20. init(option) {
  21. if (!option) {
  22. option = Object.assign({}, DOMUtilsCoreDefaultEnv);
  23. }
  24. Object.assign(DOMUtilsCoreEnv, option);
  25. },
  26. get document() {
  27. return DOMUtilsCoreEnv.document;
  28. },
  29. get window() {
  30. return DOMUtilsCoreEnv.window;
  31. },
  32. get globalThis() {
  33. return DOMUtilsCoreEnv.globalThis;
  34. },
  35. get self() {
  36. return DOMUtilsCoreEnv.self;
  37. },
  38. };
  39.  
  40. /** 通用工具类 */
  41. const CommonDOMUtils = {
  42. /**
  43. * 判断元素是否已显示或已连接
  44. * @param element
  45. */
  46. isShow(element) {
  47. return Boolean(element.getClientRects().length);
  48. },
  49. /**
  50. * 用于显示元素并获取它的高度宽度等其它属性
  51. * @param element
  52. */
  53. showElement(element) {
  54. let dupNode = element.cloneNode(true);
  55. dupNode.setAttribute("style", "visibility: hidden !important;display:block !important;");
  56. DOMUtilsCore.document.documentElement.appendChild(dupNode);
  57. return {
  58. /**
  59. * 恢复修改的style
  60. */
  61. recovery() {
  62. dupNode.remove();
  63. },
  64. };
  65. },
  66. /**
  67. * 获取元素上的Float格式的属性px
  68. * @param element
  69. * @param styleName style名
  70. */
  71. getStyleValue(element, styleName) {
  72. let view = null;
  73. let styles = null;
  74. if (element instanceof CSSStyleDeclaration) {
  75. /* 直接就获取了style属性 */
  76. styles = element;
  77. }
  78. else {
  79. view = element.ownerDocument.defaultView;
  80. if (!view || !view.opener) {
  81. view = window;
  82. }
  83. styles = view.getComputedStyle(element);
  84. }
  85. let value = parseFloat(styles[styleName]);
  86. if (isNaN(value)) {
  87. return 0;
  88. }
  89. else {
  90. return value;
  91. }
  92. },
  93. /**
  94. * 判断是否是window,例如window、self、globalThis
  95. * @param target
  96. */
  97. isWin(target) {
  98. if (typeof target !== "object") {
  99. return false;
  100. }
  101. if (target instanceof Node) {
  102. return false;
  103. }
  104. if (target === globalThis) {
  105. return true;
  106. }
  107. if (target === window) {
  108. return true;
  109. }
  110. if (target === self) {
  111. return true;
  112. }
  113. if (typeof unsafeWindow !== "undefined" &&
  114. target === unsafeWindow) {
  115. return true;
  116. }
  117. if (target?.Math?.toString() !== "[object Math]") {
  118. return false;
  119. }
  120. return true;
  121. },
  122. /**
  123. * 删除对象上的属性
  124. * @param target
  125. * @param propName
  126. */
  127. delete(target, propName) {
  128. if (typeof Reflect === "object" && Reflect.deleteProperty) {
  129. Reflect.deleteProperty(target, propName);
  130. }
  131. else {
  132. delete target[propName];
  133. }
  134. },
  135. };
  136.  
  137. /* 数据 */
  138. const DOMUtilsData = {
  139. /** .on绑定的事件 */
  140. SymbolEvents: Symbol("events_" + (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)),
  141. };
  142.  
  143. const OriginPrototype = {
  144. Object: {
  145. defineProperty: Object.defineProperty,
  146. },
  147. };
  148.  
  149. class DOMUtils {
  150. constructor(option) {
  151. DOMUtilsCore.init(option);
  152. }
  153. /** 版本号 */
  154. version = "2024.5.24";
  155. attr(element, attrName, attrValue) {
  156. if (typeof element === "string") {
  157. element = DOMUtilsCore.document.querySelector(element);
  158. }
  159. if (element == null) {
  160. return;
  161. }
  162. if (attrValue == null) {
  163. return element.getAttribute(attrName);
  164. }
  165. else {
  166. element.setAttribute(attrName, attrValue);
  167. }
  168. }
  169. /**
  170. * 创建元素
  171. * @param tagName 标签名
  172. * @param property 属性
  173. * @param attributes 元素上的自定义属性
  174. * @example
  175. * // 创建一个DIV元素,且属性class为xxx
  176. * DOMUtils.createElement("div",undefined,{ class:"xxx" });
  177. * > <div class="xxx"></div>
  178. * @example
  179. * // 创建一个DIV元素
  180. * DOMUtils.createElement("div");
  181. * > <div></div>
  182. * @example
  183. * // 创建一个DIV元素
  184. * DOMUtils.createElement("div","测试");
  185. * > <div>测试</div>
  186. */
  187. createElement(
  188. /** 元素名 */
  189. tagName,
  190. /** 属性 */
  191. property,
  192. /** 自定义属性 */
  193. attributes) {
  194. let tempElement = DOMUtilsCore.document.createElement(tagName);
  195. if (typeof property === "string") {
  196. tempElement.innerHTML = property;
  197. return tempElement;
  198. }
  199. if (property == null) {
  200. property = {};
  201. }
  202. if (attributes == null) {
  203. attributes = {};
  204. }
  205. Object.keys(property).forEach((key) => {
  206. let value = property[key];
  207. tempElement[key] = value;
  208. });
  209. Object.keys(attributes).forEach((key) => {
  210. let value = attributes[key];
  211. if (typeof value === "object") {
  212. /* object转字符串 */
  213. value = JSON.stringify(value);
  214. }
  215. else if (typeof value === "function") {
  216. /* function转字符串 */
  217. value = value.toString();
  218. }
  219. tempElement.setAttribute(key, value);
  220. });
  221. return tempElement;
  222. }
  223. css(element, property, value) {
  224. /**
  225. * 把纯数字没有px的加上
  226. */
  227. function handlePixe(propertyName, propertyValue) {
  228. let allowAddPixe = [
  229. "width",
  230. "height",
  231. "top",
  232. "left",
  233. "right",
  234. "bottom",
  235. "font-size",
  236. ];
  237. if (typeof propertyValue === "number") {
  238. propertyValue = propertyValue.toString();
  239. }
  240. if (typeof propertyValue === "string" &&
  241. allowAddPixe.includes(propertyName) &&
  242. propertyValue.match(/[0-9]$/gi)) {
  243. propertyValue = propertyValue + "px";
  244. }
  245. return propertyValue;
  246. }
  247. if (typeof element === "string") {
  248. element = DOMUtilsCore.document.querySelector(element);
  249. }
  250. if (element == null) {
  251. return;
  252. }
  253. if (typeof property === "string") {
  254. if (value == null) {
  255. return getComputedStyle(element).getPropertyValue(property);
  256. }
  257. else {
  258. if (value === "string" && value.includes("!important")) {
  259. element.style.setProperty(property, value, "important");
  260. }
  261. else {
  262. value = handlePixe(property, value);
  263. element.style.setProperty(property, value);
  264. }
  265. }
  266. }
  267. else if (typeof property === "object") {
  268. for (let prop in property) {
  269. if (typeof property[prop] === "string" &&
  270. property[prop].includes("!important")) {
  271. element.style.setProperty(prop, property[prop], "important");
  272. }
  273. else {
  274. property[prop] = handlePixe(prop, property[prop]);
  275. element.style.setProperty(prop, property[prop]);
  276. }
  277. }
  278. }
  279. }
  280. text(element, text) {
  281. if (typeof element === "string") {
  282. element = DOMUtilsCore.document.querySelector(element);
  283. }
  284. if (element == null) {
  285. return;
  286. }
  287. if (text == null) {
  288. return element.textContent || element.innerText;
  289. }
  290. else {
  291. if (text instanceof Node) {
  292. text = text.textContent || text.innerText;
  293. }
  294. if ("textContent" in element) {
  295. element.textContent = text;
  296. }
  297. else if ("innerText" in element) {
  298. element.innerText = text;
  299. }
  300. }
  301. }
  302. html(element, html) {
  303. if (typeof element === "string") {
  304. element = DOMUtilsCore.document.querySelector(element);
  305. }
  306. if (element == null) {
  307. return;
  308. }
  309. if (html == null) {
  310. return element.innerHTML;
  311. }
  312. else {
  313. if (html instanceof Node) {
  314. html = html.innerHTML;
  315. }
  316. if ("innerHTML" in element) {
  317. element.innerHTML = html;
  318. }
  319. }
  320. }
  321. /**
  322. * 绑定或触发元素的click事件
  323. * @param element 目标元素
  324. * @param handler (可选)事件处理函数
  325. * @param details (可选)赋予触发的Event的额外属性
  326. * @param useDispatchToTriggerEvent (可选)是否使用dispatchEvent来触发事件,默认true
  327. * @example
  328. * // 触发元素a.xx的click事件
  329. * DOMUtils.click(document.querySelector("a.xx"))
  330. * DOMUtils.click("a.xx")
  331. * DOMUtils.click("a.xx",function(){
  332. * console.log("触发click事件成功")
  333. * })
  334. * */
  335. click(element, handler, details, useDispatchToTriggerEvent) {
  336. let DOMUtilsContext = this;
  337. if (typeof element === "string") {
  338. element = DOMUtilsCore.document.querySelector(element);
  339. }
  340. if (element == null) {
  341. return;
  342. }
  343. if (handler == null) {
  344. DOMUtilsContext.trigger(element, "click", details, useDispatchToTriggerEvent);
  345. }
  346. else {
  347. DOMUtilsContext.on(element, "click", null, handler);
  348. }
  349. }
  350. /**
  351. * 绑定或触发元素的blur事件
  352. * @param element 目标元素
  353. * @param handler (可选)事件处理函数
  354. * @param details (可选)赋予触发的Event的额外属性
  355. * @param useDispatchToTriggerEvent (可选)是否使用dispatchEvent来触发事件,默认true
  356. * @example
  357. * // 触发元素a.xx的blur事件
  358. * DOMUtils.blur(document.querySelector("a.xx"))
  359. * DOMUtils.blur("a.xx")
  360. * DOMUtils.blur("a.xx",function(){
  361. * console.log("触发blur事件成功")
  362. * })
  363. * */
  364. blur(element, handler, details, useDispatchToTriggerEvent) {
  365. let DOMUtilsContext = this;
  366. if (typeof element === "string") {
  367. element = DOMUtilsCore.document.querySelector(element);
  368. }
  369. if (element == null) {
  370. return;
  371. }
  372. if (handler === null) {
  373. DOMUtilsContext.trigger(element, "blur", details, useDispatchToTriggerEvent);
  374. }
  375. else {
  376. DOMUtilsContext.on(element, "blur", null, handler);
  377. }
  378. }
  379. /**
  380. * 绑定或触发元素的focus事件
  381. * @param element 目标元素
  382. * @param handler (可选)事件处理函数
  383. * @param details (可选)赋予触发的Event的额外属性
  384. * @param useDispatchToTriggerEvent (可选)是否使用dispatchEvent来触发事件,默认true
  385. * @example
  386. * // 触发元素a.xx的focus事件
  387. * DOMUtils.focus(document.querySelector("a.xx"))
  388. * DOMUtils.focus("a.xx")
  389. * DOMUtils.focus("a.xx",function(){
  390. * console.log("触发focus事件成功")
  391. * })
  392. * */
  393. focus(element, handler, details, useDispatchToTriggerEvent) {
  394. let DOMUtilsContext = this;
  395. if (typeof element === "string") {
  396. element = DOMUtilsCore.document.querySelector(element);
  397. }
  398. if (element == null) {
  399. return;
  400. }
  401. if (handler == null) {
  402. DOMUtilsContext.trigger(element, "focus", details, useDispatchToTriggerEvent);
  403. }
  404. else {
  405. DOMUtilsContext.on(element, "focus", null, handler);
  406. }
  407. }
  408. /**
  409. * 获取移动元素的transform偏移
  410. */
  411. getTransform(element, isShow = false) {
  412. let DOMUtilsContext = this;
  413. let transform_left = 0;
  414. let transform_top = 0;
  415. if (!(isShow || (!isShow && CommonDOMUtils.isShow(element)))) {
  416. /* 未显示 */
  417. let { recovery } = CommonDOMUtils.showElement(element);
  418. let transformInfo = DOMUtilsContext.getTransform(element, true);
  419. recovery();
  420. return transformInfo;
  421. }
  422. let elementTransform = getComputedStyle(element).transform;
  423. if (elementTransform != null &&
  424. elementTransform !== "none" &&
  425. elementTransform !== "") {
  426. let elementTransformSplit = elementTransform
  427. .match(/\((.+)\)/)?.[1]
  428. .split(",");
  429. if (elementTransformSplit) {
  430. transform_left = Math.abs(parseInt(elementTransformSplit[4]));
  431. transform_top = Math.abs(parseInt(elementTransformSplit[5]));
  432. }
  433. else {
  434. transform_left = 0;
  435. transform_top = 0;
  436. }
  437. }
  438. return {
  439. transformLeft: transform_left,
  440. transformTop: transform_top,
  441. };
  442. }
  443. val(element, value) {
  444. if (typeof element === "string") {
  445. element = DOMUtilsCore.document.querySelector(element);
  446. }
  447. if (element == null) {
  448. return;
  449. }
  450. if (value == null) {
  451. if (element.localName === "input" &&
  452. (element.type === "checkbox" || element.type === "radio")) {
  453. return element.checked;
  454. }
  455. else {
  456. return element.value;
  457. }
  458. }
  459. else {
  460. if (element.localName === "input" &&
  461. (element.type === "checkbox" || element.type === "radio")) {
  462. element.checked = !!value;
  463. }
  464. else {
  465. element.value = value;
  466. }
  467. }
  468. }
  469. prop(element, propName, propValue) {
  470. if (element == null) {
  471. return;
  472. }
  473. if (typeof element === "string") {
  474. element = DOMUtilsCore.document.querySelector(element);
  475. }
  476. if (propValue == null) {
  477. return element[propName];
  478. }
  479. else {
  480. element[propName] = propValue;
  481. }
  482. }
  483. /**
  484. * 移除元素的属性
  485. * @param element 目标元素
  486. * @param attrName 属性名
  487. * @example
  488. * // 移除元素a.xx的属性data-value
  489. * DOMUtils.removeAttr(document.querySelector("a.xx"),"data-value")
  490. * DOMUtils.removeAttr("a.xx","data-value")
  491. * */
  492. removeAttr(element, attrName) {
  493. if (typeof element === "string") {
  494. element = DOMUtilsCore.document.querySelector(element);
  495. }
  496. if (element == null) {
  497. return;
  498. }
  499. element.removeAttribute(attrName);
  500. }
  501. /**
  502. * 移除元素class名
  503. * @param element 目标元素
  504. * @param className 类名
  505. * @example
  506. * // 移除元素a.xx的className为xx
  507. * DOMUtils.removeClass(document.querySelector("a.xx"),"xx")
  508. * DOMUtils.removeClass("a.xx","xx")
  509. */
  510. removeClass(element, className) {
  511. if (typeof element === "string") {
  512. element = DOMUtilsCore.document.querySelector(element);
  513. }
  514. if (element == null) {
  515. return;
  516. }
  517. if (className == null) {
  518. return;
  519. }
  520. element.classList.remove(className);
  521. }
  522. /**
  523. * 移除元素的属性
  524. * @param element 目标元素
  525. * @param propName 属性名
  526. * @example
  527. * // 移除元素a.xx的href属性
  528. * DOMUtils.removeProp(document.querySelector("a.xx"),"href")
  529. * DOMUtils.removeProp("a.xx","href")
  530. * */
  531. removeProp(element, propName) {
  532. if (typeof element === "string") {
  533. element = DOMUtilsCore.document.querySelector(element);
  534. }
  535. if (element == null) {
  536. return;
  537. }
  538. CommonDOMUtils.delete(element, propName);
  539. }
  540. /**
  541. * 将一个元素替换为另一个元素
  542. * @param element 目标元素
  543. * @param newElement 新元素
  544. * @example
  545. * // 替换元素a.xx为b.xx
  546. * DOMUtils.replaceWith(document.querySelector("a.xx"),document.querySelector("b.xx"))
  547. * DOMUtils.replaceWith("a.xx",'<b class="xx"></b>')
  548. */
  549. replaceWith(element, newElement) {
  550. let DOMUtilsContext = this;
  551. if (typeof element === "string") {
  552. element = DOMUtilsCore.document.querySelector(element);
  553. }
  554. if (element == null) {
  555. return;
  556. }
  557. if (typeof newElement === "string") {
  558. newElement = DOMUtilsContext.parseHTML(newElement, false, false);
  559. }
  560. if (element instanceof NodeList || element instanceof Array) {
  561. element.forEach((item) => {
  562. DOMUtilsContext.replaceWith(item, newElement);
  563. });
  564. }
  565. else {
  566. element.parentElement.replaceChild(newElement, element);
  567. }
  568. }
  569. /**
  570. * 给元素添加class
  571. * @param element 目标元素
  572. * @param className class名
  573. * @example
  574. * // 元素a.xx的className添加_vue_
  575. * DOMUtils.addClass(document.querySelector("a.xx"),"_vue_")
  576. * DOMUtils.addClass("a.xx","_vue_")
  577. * */
  578. addClass(element, className) {
  579. if (typeof element === "string") {
  580. element = DOMUtilsCore.document.querySelector(element);
  581. }
  582. if (element == null) {
  583. return;
  584. }
  585. element.classList.add(className);
  586. }
  587. /**
  588. * 函数在元素内部末尾添加子元素或HTML字符串
  589. * @param element 目标元素
  590. * @param content 子元素或HTML字符串
  591. * @example
  592. * // 元素a.xx的内部末尾添加一个元素
  593. * DOMUtils.append(document.querySelector("a.xx"),document.querySelector("b.xx"))
  594. * DOMUtils.append("a.xx","'<b class="xx"></b>")
  595. * */
  596. append(element, content) {
  597. if (typeof element === "string") {
  598. element = DOMUtilsCore.document.querySelector(element);
  599. }
  600. if (element == null) {
  601. return;
  602. }
  603. if (typeof content === "string") {
  604. element.insertAdjacentHTML("beforeend", content);
  605. }
  606. else {
  607. element.appendChild(content);
  608. }
  609. }
  610. /**
  611. * 函数 在元素内部开头添加子元素或HTML字符串
  612. * @param element 目标元素
  613. * @param content 子元素或HTML字符串
  614. * @example
  615. * // 元素a.xx内部开头添加一个元素
  616. * DOMUtils.prepend(document.querySelector("a.xx"),document.querySelector("b.xx"))
  617. * DOMUtils.prepend("a.xx","'<b class="xx"></b>")
  618. * */
  619. prepend(element, content) {
  620. if (typeof element === "string") {
  621. element = DOMUtilsCore.document.querySelector(element);
  622. }
  623. if (element == null) {
  624. return;
  625. }
  626. if (typeof content === "string") {
  627. element.insertAdjacentHTML("afterbegin", content);
  628. }
  629. else {
  630. element.insertBefore(content, element.firstChild);
  631. }
  632. }
  633. /**
  634. * 在元素后面添加兄弟元素或HTML字符串
  635. * @param element 目标元素
  636. * @param content 兄弟元素或HTML字符串
  637. * @example
  638. * // 元素a.xx后面添加一个元素
  639. * DOMUtils.after(document.querySelector("a.xx"),document.querySelector("b.xx"))
  640. * DOMUtils.after("a.xx","'<b class="xx"></b>")
  641. * */
  642. after(element, content) {
  643. if (typeof element === "string") {
  644. element = DOMUtilsCore.document.querySelector(element);
  645. }
  646. if (element == null) {
  647. return;
  648. }
  649. if (typeof content === "string") {
  650. element.insertAdjacentHTML("afterend", content);
  651. }
  652. else {
  653. element.parentElement.insertBefore(content, element.nextSibling);
  654. }
  655. }
  656. /**
  657. * 在元素前面添加兄弟元素或HTML字符串
  658. * @param element 目标元素
  659. * @param content 兄弟元素或HTML字符串
  660. * @example
  661. * // 元素a.xx前面添加一个元素
  662. * DOMUtils.before(document.querySelector("a.xx"),document.querySelector("b.xx"))
  663. * DOMUtils.before("a.xx","'<b class="xx"></b>")
  664. * */
  665. before(element, content) {
  666. if (typeof element === "string") {
  667. element = DOMUtilsCore.document.querySelector(element);
  668. }
  669. if (element == null) {
  670. return;
  671. }
  672. if (typeof content === "string") {
  673. element.insertAdjacentHTML("beforebegin", content);
  674. }
  675. else {
  676. element.parentElement.insertBefore(content, element);
  677. }
  678. }
  679. /**
  680. * 移除元素
  681. * @param target 目标元素
  682. * @example
  683. * // 元素a.xx前面添加一个元素
  684. * DOMUtils.remove(document.querySelector("a.xx"))
  685. * DOMUtils.remove(document.querySelectorAll("a.xx"))
  686. * DOMUtils.remove("a.xx")
  687. * */
  688. remove(target) {
  689. let DOMUtilsContext = this;
  690. if (typeof target === "string") {
  691. target = DOMUtilsCore.document.querySelectorAll(target);
  692. }
  693. if (target == null) {
  694. return;
  695. }
  696. if (target instanceof NodeList || target instanceof Array) {
  697. target = target;
  698. for (const element of target) {
  699. DOMUtilsContext.remove(element);
  700. }
  701. }
  702. else {
  703. target.remove();
  704. }
  705. }
  706. /**
  707. * 移除元素的所有子元素
  708. * @param element 目标元素
  709. * @example
  710. * // 移除元素a.xx元素的所有子元素
  711. * DOMUtils.empty(document.querySelector("a.xx"))
  712. * DOMUtils.empty("a.xx")
  713. * */
  714. empty(element) {
  715. if (typeof element === "string") {
  716. element = DOMUtilsCore.document.querySelector(element);
  717. }
  718. if (element == null) {
  719. return;
  720. }
  721. element.innerHTML = "";
  722. }
  723. on(element, eventType, selector, callback, option) {
  724. /**
  725. * 获取option配置
  726. * @param args
  727. * @param startIndex
  728. * @param option
  729. */
  730. function getOption(args, startIndex, option) {
  731. if (typeof args[startIndex] === "boolean") {
  732. option.capture = args[startIndex];
  733. if (typeof args[startIndex + 1] === "boolean") {
  734. option.once = args[startIndex + 1];
  735. }
  736. if (typeof args[startIndex + 2] === "boolean") {
  737. option.passive = args[startIndex + 2];
  738. }
  739. }
  740. else if (typeof args[startIndex] === "object" &&
  741. ("capture" in args[startIndex] ||
  742. "once" in args[startIndex] ||
  743. "passive" in args[startIndex])) {
  744. option.capture = args[startIndex].capture;
  745. option.once = args[startIndex].once;
  746. option.passive = args[startIndex].passive;
  747. }
  748. return option;
  749. }
  750. let DOMUtilsContext = this;
  751. let args = arguments;
  752. if (typeof element === "string") {
  753. element = DOMUtilsCore.document.querySelectorAll(element);
  754. }
  755. if (element == null) {
  756. return;
  757. }
  758. let elementList = [];
  759. if (element instanceof NodeList || Array.isArray(element)) {
  760. element = element;
  761. elementList = [...element];
  762. }
  763. else {
  764. elementList.push(element);
  765. }
  766. let eventTypeList = [];
  767. if (Array.isArray(eventType)) {
  768. eventTypeList = eventTypeList.concat(eventType);
  769. }
  770. else if (typeof eventType === "string") {
  771. eventTypeList = eventTypeList.concat(eventType.split(" "));
  772. }
  773. let _selector_ = selector;
  774. let _callback_ = callback;
  775. let _option_ = {
  776. capture: false,
  777. once: false,
  778. passive: false,
  779. };
  780. if (typeof selector === "function") {
  781. /* 这是为没有selector的情况 */
  782. _selector_ = void 0;
  783. _callback_ = selector;
  784. _option_ = getOption(args, 3, _option_);
  785. }
  786. else {
  787. /* 这是存在selector的情况 */
  788. _option_ = getOption(args, 4, _option_);
  789. }
  790. /**
  791. * 如果是once,那么删除该监听和元素上的事件和监听
  792. */
  793. function checkOptionOnceToRemoveEventListener() {
  794. if (_option_.once) {
  795. DOMUtilsContext.off(element, eventType, selector, callback, option);
  796. }
  797. }
  798. elementList.forEach((elementItem) => {
  799. function ownCallBack(event) {
  800. let target = event.target;
  801. if (_selector_) {
  802. /* 存在自定义子元素选择器 */
  803. let totalParent = CommonDOMUtils.isWin(elementItem)
  804. ? DOMUtilsCore.document.documentElement
  805. : elementItem;
  806. if (target.matches(_selector_)) {
  807. /* 当前目标可以被selector所匹配到 */
  808. _callback_.call(target, event);
  809. checkOptionOnceToRemoveEventListener();
  810. }
  811. else if (target.closest(_selector_) &&
  812. totalParent.contains(target.closest(_selector_))) {
  813. /* 在上层与主元素之间寻找可以被selector所匹配到的 */
  814. let closestElement = target.closest(_selector_);
  815. /* event的target值不能直接修改 */
  816. OriginPrototype.Object.defineProperty(event, "target", {
  817. get() {
  818. return closestElement;
  819. },
  820. });
  821. _callback_.call(closestElement, event);
  822. checkOptionOnceToRemoveEventListener();
  823. }
  824. }
  825. else {
  826. _callback_.call(elementItem, event);
  827. checkOptionOnceToRemoveEventListener();
  828. }
  829. }
  830. /* 遍历事件名设置元素事件 */
  831. eventTypeList.forEach((eventName) => {
  832. elementItem.addEventListener(eventName, ownCallBack, _option_);
  833. if (_callback_ && _callback_.delegate) {
  834. elementItem.setAttribute("data-delegate", _selector_);
  835. }
  836. /* 获取对象上的事件 */
  837. let elementEvents = elementItem[DOMUtilsData.SymbolEvents] || {};
  838. /* 初始化对象上的xx事件 */
  839. elementEvents[eventName] = elementEvents[eventName] || [];
  840. elementEvents[eventName].push({
  841. selector: _selector_,
  842. option: _option_,
  843. callback: ownCallBack,
  844. originCallBack: _callback_,
  845. });
  846. /* 覆盖事件 */
  847. elementItem[DOMUtilsData.SymbolEvents] = elementEvents;
  848. });
  849. });
  850. }
  851. off(element, eventType, selector, callback, option, filter) {
  852. /**
  853. * 获取option配置
  854. * @param args1
  855. * @param startIndex
  856. * @param option
  857. */
  858. function getOption(args1, startIndex, option) {
  859. if (typeof args1[startIndex] === "boolean") {
  860. option.capture = args1[startIndex];
  861. }
  862. else if (typeof args1[startIndex] === "object" &&
  863. "capture" in args1[startIndex]) {
  864. option.capture = args1[startIndex].capture;
  865. }
  866. return option;
  867. }
  868. let args = arguments;
  869. if (typeof element === "string") {
  870. element = DOMUtilsCore.document.querySelectorAll(element);
  871. }
  872. if (element == null) {
  873. return;
  874. }
  875. let elementList = [];
  876. if (element instanceof NodeList || Array.isArray(element)) {
  877. element = element;
  878. elementList = [...element];
  879. }
  880. else {
  881. elementList.push(element);
  882. }
  883. let eventTypeList = [];
  884. if (Array.isArray(eventType)) {
  885. eventTypeList = eventTypeList.concat(eventType);
  886. }
  887. else if (typeof eventType === "string") {
  888. eventTypeList = eventTypeList.concat(eventType.split(" "));
  889. }
  890. /**
  891. * 子元素选择器
  892. */
  893. let _selector_ = selector;
  894. /**
  895. * 事件的回调函数
  896. */
  897. let _callback_ = callback;
  898. /**
  899. * 事件的配置
  900. */
  901. let _option_ = {
  902. capture: false,
  903. };
  904. if (typeof selector === "function") {
  905. /* 这是为没有selector的情况 */
  906. _selector_ = void 0;
  907. _callback_ = selector;
  908. _option_ = getOption(args, 3, _option_);
  909. }
  910. else {
  911. _option_ = getOption(args, 4, _option_);
  912. }
  913. elementList.forEach((elementItem) => {
  914. /* 获取对象上的事件 */
  915. let elementEvents = elementItem[DOMUtilsData.SymbolEvents] || {};
  916. eventTypeList.forEach((eventName) => {
  917. let handlers = elementEvents[eventName] || [];
  918. if (typeof filter === "function") {
  919. handlers = handlers.filter(filter);
  920. }
  921. for (let index = 0; index < handlers.length; index++) {
  922. let handler = handlers[index];
  923. let flag = false;
  924. if (!_selector_ || handler.selector === _selector_) {
  925. /* selector不为空,进行selector判断 */
  926. flag = true;
  927. }
  928. if (!_callback_ ||
  929. handler.callback === _callback_ ||
  930. handler.originCallBack === _callback_) {
  931. /* callback不为空,进行callback判断 */
  932. flag = true;
  933. }
  934. if (flag) {
  935. elementItem.removeEventListener(eventName, handler.callback, _option_);
  936. handlers.splice(index--, 1);
  937. }
  938. }
  939. if (handlers.length === 0) {
  940. /* 如果没有任意的handler,那么删除该属性 */
  941. CommonDOMUtils.delete(elementEvents, eventType);
  942. }
  943. });
  944. elementItem[DOMUtilsData.SymbolEvents] = elementEvents;
  945. });
  946. }
  947. /**
  948. * 取消绑定所有的事件
  949. * @param element 需要取消绑定的元素|元素数组
  950. * @param eventType (可选)需要取消监听的事件
  951. */
  952. offAll(element, eventType) {
  953. if (typeof element === "string") {
  954. element = DOMUtilsCore.document.querySelectorAll(element);
  955. }
  956. if (element == null) {
  957. return;
  958. }
  959. let elementList = [];
  960. if (element instanceof NodeList || Array.isArray(element)) {
  961. element = element;
  962. elementList = [...element];
  963. }
  964. else {
  965. elementList.push(element);
  966. }
  967. let eventTypeList = [];
  968. if (Array.isArray(eventType)) {
  969. eventTypeList = eventTypeList.concat(eventType);
  970. }
  971. else if (typeof eventType === "string") {
  972. eventTypeList = eventTypeList.concat(eventType.split(" "));
  973. }
  974. elementList.forEach((elementItem) => {
  975. Object.getOwnPropertySymbols(elementItem).forEach((symbolEvents) => {
  976. if (!symbolEvents.toString().startsWith("Symbol(events_")) {
  977. return;
  978. }
  979. let elementEvents = elementItem[symbolEvents] || {};
  980. let iterEventNameList = eventTypeList.length
  981. ? eventTypeList
  982. : Object.keys(elementEvents);
  983. iterEventNameList.forEach((eventName) => {
  984. let handlers = elementEvents[eventName];
  985. if (!handlers) {
  986. return;
  987. }
  988. for (const handler of handlers) {
  989. elementItem.removeEventListener(eventName, handler.callback, {
  990. capture: handler["option"]["capture"],
  991. });
  992. }
  993. CommonDOMUtils.delete(elementItem[symbolEvents], eventName);
  994. });
  995. });
  996. });
  997. }
  998. /**
  999. * 主动触发事件
  1000. * @param element 需要触发的元素|元素数组|window
  1001. * @param eventType 需要触发的事件
  1002. * @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
  1003. * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true
  1004. * @example
  1005. * // 触发元素a.xx的click事件
  1006. * DOMUtils.trigger(document.querySelector("a.xx"),"click")
  1007. * DOMUtils.trigger("a.xx","click")
  1008. * // 触发元素a.xx的click、tap、hover事件
  1009. * DOMUtils.trigger(document.querySelector("a.xx"),"click tap hover")
  1010. * DOMUtils.trigger("a.xx",["click","tap","hover"])
  1011. */
  1012. trigger(element, eventType, details, useDispatchToTriggerEvent = true) {
  1013. if (typeof element === "string") {
  1014. element = DOMUtilsCore.document.querySelector(element);
  1015. }
  1016. if (element == null) {
  1017. return;
  1018. }
  1019. let elementList = [];
  1020. if (element instanceof NodeList || Array.isArray(element)) {
  1021. element = element;
  1022. elementList = [...element];
  1023. }
  1024. else {
  1025. elementList = [element];
  1026. }
  1027. let eventTypeList = [];
  1028. if (Array.isArray(eventType)) {
  1029. eventTypeList = eventType;
  1030. }
  1031. else if (typeof eventType === "string") {
  1032. eventTypeList = eventType.split(" ");
  1033. }
  1034. elementList.forEach((elementItem) => {
  1035. /* 获取对象上的事件 */
  1036. let events = elementItem[DOMUtilsData.SymbolEvents] || {};
  1037. eventTypeList.forEach((_eventType_) => {
  1038. let event = null;
  1039. if (details && details instanceof Event) {
  1040. event = details;
  1041. }
  1042. else {
  1043. event = new Event(_eventType_);
  1044. if (details) {
  1045. Object.keys(details).forEach((keyName) => {
  1046. event[keyName] = details[keyName];
  1047. });
  1048. }
  1049. }
  1050. if (useDispatchToTriggerEvent == false && _eventType_ in events) {
  1051. events[_eventType_].forEach((eventsItem) => {
  1052. eventsItem.callback(event);
  1053. });
  1054. }
  1055. else {
  1056. elementItem.dispatchEvent(event);
  1057. }
  1058. });
  1059. });
  1060. }
  1061. /**
  1062. * 获取元素相对于文档的偏移坐标(加上文档的滚动条)
  1063. * @param element 目标元素
  1064. * @example
  1065. * // 获取元素a.xx的对于文档的偏移坐标
  1066. * DOMUtils.offset(document.querySelector("a.xx"))
  1067. * DOMUtils.offset("a.xx")
  1068. * > 0
  1069. */
  1070. offset(element) {
  1071. if (typeof element === "string") {
  1072. element = DOMUtilsCore.document.querySelector(element);
  1073. }
  1074. if (element == null) {
  1075. return;
  1076. }
  1077. let rect = element.getBoundingClientRect();
  1078. return {
  1079. /** y轴偏移 */
  1080. top: rect.top + DOMUtilsCore.globalThis.scrollY,
  1081. /** x轴偏移 */
  1082. left: rect.left + DOMUtilsCore.globalThis.scrollX,
  1083. };
  1084. }
  1085. width(element, isShow = false) {
  1086. let DOMUtilsContext = this;
  1087. if (typeof element === "string") {
  1088. element = DOMUtilsCore.document.querySelector(element);
  1089. }
  1090. if (element == null) {
  1091. return;
  1092. }
  1093. if (CommonDOMUtils.isWin(element)) {
  1094. return DOMUtilsCore.window.document.documentElement.clientWidth;
  1095. }
  1096. if (element.nodeType === 9) {
  1097. /* Document文档节点 */
  1098. element = element;
  1099. return Math.max(element.body.scrollWidth, element.documentElement.scrollWidth, element.body.offsetWidth, element.documentElement.offsetWidth, element.documentElement.clientWidth);
  1100. }
  1101. if (isShow || (!isShow && CommonDOMUtils.isShow(element))) {
  1102. /* 已显示 */
  1103. /* 不从style中获取对应的宽度,因为可能使用了class定义了width !important */
  1104. element = element;
  1105. /* 如果element.style.width为空 则从css里面获取是否定义了width信息如果定义了 则读取css里面定义的宽度width */
  1106. if (parseFloat(CommonDOMUtils.getStyleValue(element, "width").toString()) >
  1107. 0) {
  1108. return parseFloat(CommonDOMUtils.getStyleValue(element, "width").toString());
  1109. }
  1110. /* 如果从css里获取到的值不是大于0 可能是auto 则通过offsetWidth来进行计算 */
  1111. if (element.offsetWidth > 0) {
  1112. let borderLeftWidth = CommonDOMUtils.getStyleValue(element, "borderLeftWidth");
  1113. let borderRightWidth = CommonDOMUtils.getStyleValue(element, "borderRightWidth");
  1114. let paddingLeft = CommonDOMUtils.getStyleValue(element, "paddingLeft");
  1115. let paddingRight = CommonDOMUtils.getStyleValue(element, "paddingRight");
  1116. let backHeight = parseFloat(element.offsetWidth.toString()) -
  1117. parseFloat(borderLeftWidth.toString()) -
  1118. parseFloat(borderRightWidth.toString()) -
  1119. parseFloat(paddingLeft.toString()) -
  1120. parseFloat(paddingRight.toString());
  1121. return parseFloat(backHeight.toString());
  1122. }
  1123. return 0;
  1124. }
  1125. else {
  1126. /* 未显示 */
  1127. element = element;
  1128. let { recovery } = CommonDOMUtils.showElement(element);
  1129. let width = DOMUtilsContext.width(element, true);
  1130. recovery();
  1131. return width;
  1132. }
  1133. }
  1134. height(element, isShow = false) {
  1135. let DOMUtilsContext = this;
  1136. if (CommonDOMUtils.isWin(element)) {
  1137. return DOMUtilsCore.window.document.documentElement.clientHeight;
  1138. }
  1139. if (typeof element === "string") {
  1140. element = DOMUtilsCore.document.querySelector(element);
  1141. }
  1142. if (element == null) {
  1143. // @ts-ignore
  1144. return;
  1145. }
  1146. if (element.nodeType === 9) {
  1147. element = element;
  1148. /* Document文档节点 */
  1149. return Math.max(element.body.scrollHeight, element.documentElement.scrollHeight, element.body.offsetHeight, element.documentElement.offsetHeight, element.documentElement.clientHeight);
  1150. }
  1151. if (isShow || (!isShow && CommonDOMUtils.isShow(element))) {
  1152. element = element;
  1153. /* 已显示 */
  1154. /* 从style中获取对应的高度,因为可能使用了class定义了width !important */
  1155. /* 如果element.style.height为空 则从css里面获取是否定义了height信息如果定义了 则读取css里面定义的高度height */
  1156. if (parseFloat(CommonDOMUtils.getStyleValue(element, "height").toString()) >
  1157. 0) {
  1158. return parseFloat(CommonDOMUtils.getStyleValue(element, "height").toString());
  1159. }
  1160. /* 如果从css里获取到的值不是大于0 可能是auto 则通过offsetHeight来进行计算 */
  1161. if (element.offsetHeight > 0) {
  1162. let borderTopWidth = CommonDOMUtils.getStyleValue(element, "borderTopWidth");
  1163. let borderBottomWidth = CommonDOMUtils.getStyleValue(element, "borderBottomWidth");
  1164. let paddingTop = CommonDOMUtils.getStyleValue(element, "paddingTop");
  1165. let paddingBottom = CommonDOMUtils.getStyleValue(element, "paddingBottom");
  1166. let backHeight = parseFloat(element.offsetHeight.toString()) -
  1167. parseFloat(borderTopWidth.toString()) -
  1168. parseFloat(borderBottomWidth.toString()) -
  1169. parseFloat(paddingTop.toString()) -
  1170. parseFloat(paddingBottom.toString());
  1171. return parseFloat(backHeight.toString());
  1172. }
  1173. return 0;
  1174. }
  1175. else {
  1176. /* 未显示 */
  1177. element = element;
  1178. let { recovery } = CommonDOMUtils.showElement(element);
  1179. let height = DOMUtilsContext.height(element, true);
  1180. recovery();
  1181. return height;
  1182. }
  1183. }
  1184. outerWidth(element, isShow = false) {
  1185. let DOMUtilsContext = this;
  1186. if (CommonDOMUtils.isWin(element)) {
  1187. return DOMUtilsCore.window.innerWidth;
  1188. }
  1189. if (typeof element === "string") {
  1190. element = DOMUtilsCore.document.querySelector(element);
  1191. }
  1192. if (element == null) {
  1193. // @ts-ignore
  1194. return;
  1195. }
  1196. element = element;
  1197. if (isShow || (!isShow && CommonDOMUtils.isShow(element))) {
  1198. let style = getComputedStyle(element, null);
  1199. let marginLeft = CommonDOMUtils.getStyleValue(style, "marginLeft");
  1200. let marginRight = CommonDOMUtils.getStyleValue(style, "marginRight");
  1201. return element.offsetWidth + marginLeft + marginRight;
  1202. }
  1203. else {
  1204. let { recovery } = CommonDOMUtils.showElement(element);
  1205. let outerWidth = DOMUtilsContext.outerWidth(element, true);
  1206. recovery();
  1207. return outerWidth;
  1208. }
  1209. }
  1210. outerHeight(element, isShow = false) {
  1211. let DOMUtilsContext = this;
  1212. if (CommonDOMUtils.isWin(element)) {
  1213. return DOMUtilsCore.window.innerHeight;
  1214. }
  1215. if (typeof element === "string") {
  1216. element = DOMUtilsCore.document.querySelector(element);
  1217. }
  1218. if (element == null) {
  1219. // @ts-ignore
  1220. return;
  1221. }
  1222. element = element;
  1223. if (isShow || (!isShow && CommonDOMUtils.isShow(element))) {
  1224. let style = getComputedStyle(element, null);
  1225. let marginTop = CommonDOMUtils.getStyleValue(style, "marginTop");
  1226. let marginBottom = CommonDOMUtils.getStyleValue(style, "marginBottom");
  1227. return element.offsetHeight + marginTop + marginBottom;
  1228. }
  1229. else {
  1230. let { recovery } = CommonDOMUtils.showElement(element);
  1231. let outerHeight = DOMUtilsContext.outerHeight(element, true);
  1232. recovery();
  1233. return outerHeight;
  1234. }
  1235. }
  1236. /**
  1237. * 等待文档加载完成后执行指定的函数
  1238. * @param callback 需要执行的函数
  1239. * @example
  1240. * DOMUtils.ready(function(){
  1241. * console.log("文档加载完毕")
  1242. * })
  1243. */
  1244. ready(callback) {
  1245. let DOMUtilsContext = this;
  1246. function completed() {
  1247. DOMUtilsContext.off(document, "DOMContentLoaded", completed);
  1248. DOMUtilsContext.off(globalThis, "load", completed);
  1249. callback();
  1250. }
  1251. if (document.readyState === "complete" ||
  1252. (document.readyState !== "loading" &&
  1253. !document.documentElement.doScroll)) {
  1254. setTimeout(callback);
  1255. }
  1256. else {
  1257. /* 监听DOMContentLoaded事件 */
  1258. DOMUtilsContext.on(document, "DOMContentLoaded", completed);
  1259. /* 监听load事件 */
  1260. DOMUtilsContext.on(globalThis, "load", completed);
  1261. }
  1262. }
  1263. /**
  1264. * 在一定时间内改变元素的样式属性,实现动画效果
  1265. * @param element 需要进行动画的元素
  1266. * @param styles 动画结束时元素的样式属性
  1267. * @param duration 动画持续时间,单位为毫秒
  1268. * @param callback 动画结束后执行的函数
  1269. * @example
  1270. * // 监听元素a.xx的从显示变为隐藏
  1271. * DOMUtils.animate(document.querySelector("a.xx"),{ top:100},1000,function(){
  1272. * console.log("已往上位移100px")
  1273. * })
  1274. */
  1275. animate(element, styles, duration = 1000, callback = null) {
  1276. if (typeof element === "string") {
  1277. element = DOMUtilsCore.document.querySelector(element);
  1278. }
  1279. if (element == null) {
  1280. return;
  1281. }
  1282. if (typeof duration !== "number" || duration <= 0) {
  1283. throw new TypeError("duration must be a positive number");
  1284. }
  1285. if (typeof callback !== "function" && callback !== void 0) {
  1286. throw new TypeError("callback must be a function or null");
  1287. }
  1288. if (typeof styles !== "object" || styles === void 0) {
  1289. throw new TypeError("styles must be an object");
  1290. }
  1291. if (Object.keys(styles).length === 0) {
  1292. throw new Error("styles must contain at least one property");
  1293. }
  1294. let start = performance.now();
  1295. let from = {};
  1296. let to = {};
  1297. for (let prop in styles) {
  1298. from[prop] = element.style[prop] || getComputedStyle(element)[prop];
  1299. to[prop] = styles[prop];
  1300. }
  1301. let timer = setInterval(function () {
  1302. let timePassed = performance.now() - start;
  1303. let progress = timePassed / duration;
  1304. if (progress > 1) {
  1305. progress = 1;
  1306. }
  1307. for (let prop in styles) {
  1308. element.style[prop] =
  1309. from[prop] + (to[prop] - from[prop]) * progress + "px";
  1310. }
  1311. if (progress === 1) {
  1312. clearInterval(timer);
  1313. if (callback) {
  1314. callback();
  1315. }
  1316. }
  1317. }, 10);
  1318. }
  1319. /**
  1320. * 将一个元素包裹在指定的HTML元素中
  1321. * @param element 要包裹的元素
  1322. * @param wrapperHTML 要包裹的HTML元素的字符串表示形式
  1323. * @example
  1324. * // 将a.xx元素外面包裹一层div
  1325. * DOMUtils.wrap(document.querySelector("a.xx"),"<div></div>")
  1326. */
  1327. wrap(element, wrapperHTML) {
  1328. if (typeof element === "string") {
  1329. element = DOMUtilsCore.document.querySelector(element);
  1330. }
  1331. if (element == null) {
  1332. return;
  1333. }
  1334. element = element;
  1335. // 创建一个新的div元素,并将wrapperHTML作为其innerHTML
  1336. let wrapper = DOMUtilsCore.document.createElement("div");
  1337. wrapper.innerHTML = wrapperHTML;
  1338. let wrapperFirstChild = wrapper.firstChild;
  1339. // 将要包裹的元素插入目标元素前面
  1340. element.parentElement.insertBefore(wrapperFirstChild, element);
  1341. // 将要包裹的元素移动到wrapper中
  1342. wrapperFirstChild.appendChild(element);
  1343. }
  1344. prev(element) {
  1345. if (typeof element === "string") {
  1346. element = DOMUtilsCore.document.querySelector(element);
  1347. }
  1348. if (element == null) {
  1349. return;
  1350. }
  1351. return element.previousElementSibling;
  1352. }
  1353. next(element) {
  1354. if (typeof element === "string") {
  1355. element = DOMUtilsCore.document.querySelector(element);
  1356. }
  1357. if (element == null) {
  1358. return;
  1359. }
  1360. return element.nextElementSibling;
  1361. }
  1362. /**
  1363. * 取消挂载在window下的DOMUtils并返回DOMUtils
  1364. * @example
  1365. * let DOMUtils = window.DOMUtils.noConflict()
  1366. */
  1367. noConflict() {
  1368. if (DOMUtilsCore.window.DOMUtils) {
  1369. CommonDOMUtils.delete(window, "DOMUtils");
  1370. }
  1371. DOMUtilsCore.window.DOMUtils = this;
  1372. return this;
  1373. }
  1374. siblings(element) {
  1375. if (typeof element === "string") {
  1376. element = DOMUtilsCore.document.querySelector(element);
  1377. }
  1378. if (element == null) {
  1379. return;
  1380. }
  1381. return Array.from(element.parentElement
  1382. .children).filter((child) => child !== element);
  1383. }
  1384. /**
  1385. * 获取当前元素的父元素
  1386. * @param element 当前元素
  1387. * @returns 父元素
  1388. * @example
  1389. * // 获取a.xx元素的父元素
  1390. * DOMUtils.parent(document.querySelector("a.xx"))
  1391. * DOMUtils.parent("a.xx")
  1392. * > <div ...>....</div>
  1393. */
  1394. parent(element) {
  1395. let DOMUtilsContext = this;
  1396. if (typeof element === "string") {
  1397. element = DOMUtilsCore.document.querySelector(element);
  1398. }
  1399. if (element == null) {
  1400. return;
  1401. }
  1402. if (element instanceof NodeList || element instanceof Array) {
  1403. element = element;
  1404. let resultArray = [];
  1405. element.forEach((eleItem) => {
  1406. resultArray.push(DOMUtilsContext.parent(eleItem));
  1407. });
  1408. return resultArray;
  1409. }
  1410. else {
  1411. return element.parentElement;
  1412. }
  1413. }
  1414. parseHTML(html, useParser = false, isComplete = false) {
  1415. function parseHTMLByDOMParser() {
  1416. let parser = new DOMParser();
  1417. if (isComplete) {
  1418. return parser.parseFromString(html, "text/html");
  1419. }
  1420. else {
  1421. return parser.parseFromString(html, "text/html").body.firstChild;
  1422. }
  1423. }
  1424. function parseHTMLByCreateDom() {
  1425. let tempDIV = DOMUtilsCore.document.createElement("div");
  1426. tempDIV.innerHTML = html;
  1427. if (isComplete) {
  1428. return tempDIV;
  1429. }
  1430. else {
  1431. return tempDIV.firstChild;
  1432. }
  1433. }
  1434. if (useParser) {
  1435. return parseHTMLByDOMParser();
  1436. }
  1437. else {
  1438. return parseHTMLByCreateDom();
  1439. }
  1440. }
  1441. /**
  1442. * 当鼠标移入或移出元素时触发事件
  1443. * @param element 当前元素
  1444. * @param handler 事件处理函数
  1445. * @param option 配置
  1446. * @example
  1447. * // 监听a.xx元素的移入或移出
  1448. * DOMUtils.hover(document.querySelector("a.xx"),()=>{
  1449. * console.log("移入/移除");
  1450. * })
  1451. * DOMUtils.hover("a.xx",()=>{
  1452. * console.log("移入/移除");
  1453. * })
  1454. */
  1455. hover(element, handler, option) {
  1456. let DOMUtilsContext = this;
  1457. if (typeof element === "string") {
  1458. element = DOMUtilsCore.document.querySelector(element);
  1459. }
  1460. if (element == null) {
  1461. return;
  1462. }
  1463. DOMUtilsContext.on(element, "mouseenter", null, handler, option);
  1464. DOMUtilsContext.on(element, "mouseleave", null, handler, option);
  1465. }
  1466. /**
  1467. * 显示元素
  1468. * @param target 当前元素
  1469. * @example
  1470. * // 显示a.xx元素
  1471. * DOMUtils.show(document.querySelector("a.xx"))
  1472. * DOMUtils.show(document.querySelectorAll("a.xx"))
  1473. * DOMUtils.show("a.xx")
  1474. */
  1475. show(target) {
  1476. let DOMUtilsContext = this;
  1477. if (target == null) {
  1478. return;
  1479. }
  1480. if (typeof target === "string") {
  1481. target = DOMUtilsCore.document.querySelectorAll(target);
  1482. }
  1483. if (target instanceof NodeList || target instanceof Array) {
  1484. target = target;
  1485. for (const element of target) {
  1486. DOMUtilsContext.show(element);
  1487. }
  1488. }
  1489. else {
  1490. target = target;
  1491. target.style.display = "";
  1492. if (!CommonDOMUtils.isShow(target)) {
  1493. /* 仍然是不显示,尝试使用强覆盖 */
  1494. target.style.setProperty("display", "unset", "important");
  1495. }
  1496. }
  1497. }
  1498. /**
  1499. * 隐藏元素
  1500. * @param target 当前元素
  1501. * @example
  1502. * // 隐藏a.xx元素
  1503. * DOMUtils.hide(document.querySelector("a.xx"))
  1504. * DOMUtils.hide(document.querySelectorAll("a.xx"))
  1505. * DOMUtils.hide("a.xx")
  1506. */
  1507. hide(target) {
  1508. let DOMUtilsContext = this;
  1509. if (target == null) {
  1510. return;
  1511. }
  1512. if (typeof target === "string") {
  1513. target = DOMUtilsCore.document.querySelectorAll(target);
  1514. }
  1515. if (target instanceof NodeList || target instanceof Array) {
  1516. target = target;
  1517. for (const element of target) {
  1518. DOMUtilsContext.hide(element);
  1519. }
  1520. }
  1521. else {
  1522. target = target;
  1523. target.style.display = "none";
  1524. if (CommonDOMUtils.isShow(target)) {
  1525. /* 仍然是显示,尝试使用强覆盖 */
  1526. target.style.setProperty("display", "none", "important");
  1527. }
  1528. }
  1529. }
  1530. /**
  1531. * 当按键松开时触发事件
  1532. * keydown - > keypress - > keyup
  1533. * @param target 当前元素
  1534. * @param handler 事件处理函数
  1535. * @param option 配置
  1536. * @example
  1537. * // 监听a.xx元素的按键松开
  1538. * DOMUtils.keyup(document.querySelector("a.xx"),()=>{
  1539. * console.log("按键松开");
  1540. * })
  1541. * DOMUtils.keyup("a.xx",()=>{
  1542. * console.log("按键松开");
  1543. * })
  1544. */
  1545. keyup(target, handler, option) {
  1546. let DOMUtilsContext = this;
  1547. if (target == null) {
  1548. return;
  1549. }
  1550. if (typeof target === "string") {
  1551. target = DOMUtilsCore.document.querySelector(target);
  1552. }
  1553. DOMUtilsContext.on(target, "keyup", null, handler, option);
  1554. }
  1555. /**
  1556. * 当按键按下时触发事件
  1557. * keydown - > keypress - > keyup
  1558. * @param target 目标
  1559. * @param handler 事件处理函数
  1560. * @param option 配置
  1561. * @example
  1562. * // 监听a.xx元素的按键按下
  1563. * DOMUtils.keydown(document.querySelector("a.xx"),()=>{
  1564. * console.log("按键按下");
  1565. * })
  1566. * DOMUtils.keydown("a.xx",()=>{
  1567. * console.log("按键按下");
  1568. * })
  1569. */
  1570. keydown(target, handler, option) {
  1571. let DOMUtilsContext = this;
  1572. if (target == null) {
  1573. return;
  1574. }
  1575. if (typeof target === "string") {
  1576. target = DOMUtilsCore.document.querySelector(target);
  1577. }
  1578. DOMUtilsContext.on(target, "keydown", null, handler, option);
  1579. }
  1580. /**
  1581. * 当按键按下时触发事件
  1582. * keydown - > keypress - > keyup
  1583. * @param target 目标
  1584. * @param handler 事件处理函数
  1585. * @param option 配置
  1586. * @example
  1587. * // 监听a.xx元素的按键按下
  1588. * DOMUtils.keypress(document.querySelector("a.xx"),()=>{
  1589. * console.log("按键按下");
  1590. * })
  1591. * DOMUtils.keypress("a.xx",()=>{
  1592. * console.log("按键按下");
  1593. * })
  1594. */
  1595. keypress(target, handler, option) {
  1596. let DOMUtilsContext = this;
  1597. if (target == null) {
  1598. return;
  1599. }
  1600. if (typeof target === "string") {
  1601. target = DOMUtilsCore.document.querySelector(target);
  1602. }
  1603. DOMUtilsContext.on(target, "keypress", null, handler, option);
  1604. }
  1605. /**
  1606. * 淡入元素
  1607. * @param element 当前元素
  1608. * @param duration 动画持续时间(毫秒),默认400毫秒
  1609. * @param callback 动画结束的回调
  1610. * @example
  1611. * // 元素a.xx淡入
  1612. * DOMUtils.fadeIn(document.querySelector("a.xx"),2500,()=>{
  1613. * console.log("淡入完毕");
  1614. * })
  1615. * DOMUtils.fadeIn("a.xx",undefined,()=>{
  1616. * console.log("淡入完毕");
  1617. * })
  1618. */
  1619. fadeIn(element, duration = 400, callback) {
  1620. if (element == null) {
  1621. return;
  1622. }
  1623. if (typeof element === "string") {
  1624. element = DOMUtilsCore.document.querySelector(element);
  1625. }
  1626. element = element;
  1627. element.style.opacity = "0";
  1628. element.style.display = "";
  1629. let start = null;
  1630. let timer = null;
  1631. function step(timestamp) {
  1632. if (!start)
  1633. start = timestamp;
  1634. let progress = timestamp - start;
  1635. element = element;
  1636. element.style.opacity = Math.min(progress / duration, 1).toString();
  1637. if (progress < duration) {
  1638. DOMUtilsCore.window.requestAnimationFrame(step);
  1639. }
  1640. else {
  1641. if (callback && typeof callback === "function") {
  1642. callback();
  1643. }
  1644. DOMUtilsCore.window.cancelAnimationFrame(timer);
  1645. }
  1646. }
  1647. timer = DOMUtilsCore.window.requestAnimationFrame(step);
  1648. }
  1649. /**
  1650. * 淡出元素
  1651. * @param element 当前元素
  1652. * @param duration 动画持续时间(毫秒),默认400毫秒
  1653. * @param callback 动画结束的回调
  1654. * @example
  1655. * // 元素a.xx淡出
  1656. * DOMUtils.fadeOut(document.querySelector("a.xx"),2500,()=>{
  1657. * console.log("淡出完毕");
  1658. * })
  1659. * DOMUtils.fadeOut("a.xx",undefined,()=>{
  1660. * console.log("淡出完毕");
  1661. * })
  1662. */
  1663. fadeOut(element, duration = 400, callback) {
  1664. if (element == null) {
  1665. return;
  1666. }
  1667. if (typeof element === "string") {
  1668. element = DOMUtilsCore.document.querySelector(element);
  1669. }
  1670. element = element;
  1671. element.style.opacity = "1";
  1672. let start = null;
  1673. let timer = null;
  1674. function step(timestamp) {
  1675. if (!start)
  1676. start = timestamp;
  1677. let progress = timestamp - start;
  1678. element = element;
  1679. element.style.opacity = Math.max(1 - progress / duration, 0).toString();
  1680. if (progress < duration) {
  1681. DOMUtilsCore.window.requestAnimationFrame(step);
  1682. }
  1683. else {
  1684. element.style.display = "none";
  1685. if (typeof callback === "function") {
  1686. callback();
  1687. }
  1688. DOMUtilsCore.window.cancelAnimationFrame(timer);
  1689. }
  1690. }
  1691. timer = DOMUtilsCore.window.requestAnimationFrame(step);
  1692. }
  1693. /**
  1694. * 切换元素的显示和隐藏状态
  1695. * @param element 当前元素
  1696. * @example
  1697. * // 如果元素a.xx当前是隐藏,则显示,如果是显示,则隐藏
  1698. * DOMUtils.toggle(document.querySelector("a.xx"))
  1699. * DOMUtils.toggle("a.xx")
  1700. */
  1701. toggle(element) {
  1702. let DOMUtilsContext = this;
  1703. if (typeof element === "string") {
  1704. element = DOMUtilsCore.document.querySelector(element);
  1705. }
  1706. if (element == null) {
  1707. return;
  1708. }
  1709. if (getComputedStyle(element).getPropertyValue("display") === "none") {
  1710. DOMUtilsContext.show(element);
  1711. }
  1712. else {
  1713. DOMUtilsContext.hide(element);
  1714. }
  1715. }
  1716. /**
  1717. * 创建一个新的DOMUtils实例
  1718. * @param option
  1719. * @returns
  1720. */
  1721. createDOMUtils(option) {
  1722. return new DOMUtils(option);
  1723. }
  1724. }
  1725. let domUtils = new DOMUtils();
  1726.  
  1727. return domUtils;
  1728.  
  1729. }));
  1730. //# sourceMappingURL=index.umd.js.map

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址