术语


把提供给其他人用的工具代码叫做库,比如jQuery, Underscore
API
库暴露出来的函数或属性叫做API(应用编程接口)
框架
当你的库变得很大,并且需要学习才能看懂
那这个库就叫框架,比如Vue/React

封装

  1. window.dom = {
  2. create: function (string) {
  3. // template可以容纳任何元素
  4. let container = document.createElement("template");
  5. container.innerHTML = string.trim();
  6. return container.content.firstChild;
  7. },
  8. // 可以省去 : function
  9. // 把node2放到node1的后面
  10. after(node1, node2) {
  11. node1.parentNode.insertBefore(node2, node1.nextSibling);
  12. },
  13. before(node1, node2) {
  14. node1.parentNode.insertBefore(node2, node1);
  15. },
  16. append(parent, child) {
  17. parent.appendChild(child);
  18. },
  19. // 新增父节点
  20. wrap(parent, node) {
  21. dom.before(node, parent);
  22. dom.append(parent, node);
  23. },
  24. remove(node) {
  25. //node.remove()
  26. node.parentNode.removeChild(node);
  27. return node;
  28. },
  29. empty(node) {
  30. const { childNodes } = node;
  31. const array = [];
  32. // for (let i = 0; i < childNodes.length; i++) {
  33. // array.push(dom.remove(childNodes[i]));
  34. // }
  35. // length是实时变化的,上面方法不可行
  36. let x = node.firstChild;
  37. while (x) {
  38. array.push(dom.remove(node.firstChild));
  39. x = node.firstChild;
  40. }
  41. return array;
  42. },
  43. // 设置/获取属性
  44. attr(node, name, value) {
  45. // 重载
  46. if (arguments.length === 3) {
  47. node.setAttribute(name, value);
  48. } else if (arguments.length === 2) {
  49. return node.getAttribute(name);
  50. }
  51. },
  52. text(node, string) {
  53. // 适配
  54. if (arguments.length === 2) {
  55. if ("innerText" in node) {
  56. node.innerText = string; // ie
  57. } else {
  58. node.textContent = string; // firefox
  59. }
  60. } else if (arguments.length === 1) {
  61. if ("innerText" in node) {
  62. return node.innerText;
  63. } else {
  64. return node.textContent;
  65. }
  66. }
  67. },
  68. html(node, value) {
  69. if (arguments.length === 2) {
  70. node.innerHTML = value;
  71. } else if (arguments.length === 1) {
  72. return node.innerHTML;
  73. }
  74. },
  75. style(node, name, value) {
  76. if (arguments.length === 3) {
  77. // dom.style(div, 'color', 'red')
  78. node.style[name] = value;
  79. } else if (arguments.length === 2) {
  80. if (typeof name === "string") {
  81. // dom.style(div, 'color')
  82. return node.style[name];
  83. } else if (name instanceof Object) {
  84. //dom.style(div, {color: 'red'})
  85. for (let key in name) {
  86. node.style[key] = name[key];
  87. }
  88. }
  89. }
  90. },
  91. class: {
  92. add(node, className) {
  93. node.classList.add(className);
  94. },
  95. remove(node, className) {
  96. node.classList.remove(className);
  97. },
  98. has(node, className) {
  99. return node.classList.contains(className);
  100. },
  101. },
  102. on(node, eventName, fn) {
  103. node.addEventListener(eventName, fn);
  104. },
  105. off(node, eventName, fn) {
  106. node.removeEventListener(eventName, fn);
  107. },
  108. find(selector, scope) {
  109. // const div = dom.find("#test")[0]
  110. return (scope || document).querySelectorAll(selector);
  111. },
  112. parent(node) {
  113. return node.parentNode;
  114. },
  115. children(node) {
  116. return node.children;
  117. },
  118. siblings(node) {
  119. return Array.from(node.parentNode.children).filter((n) => n !== node);
  120. },
  121. next(node) {
  122. let x = node.nextSibling;
  123. while (x && x.nodeType === 3) {
  124. x = x.nextSibling;
  125. }
  126. return x;
  127. },
  128. previous(node) {
  129. let x = node.previousSibling;
  130. while (x && x.nodeType === 3) {
  131. x = x.previousSibling;
  132. }
  133. return x;
  134. },
  135. each(nodeList, fn) {
  136. for (let i = 0; i < nodeList.length; i++) {
  137. fn.call(null, nodeList[i]);
  138. }
  139. },
  140. index(node) {
  141. const list = dom.children(node.parentNode);
  142. let i;
  143. for (i = 0; i < list.length; i++) {
  144. if (list[i] === node) {
  145. break;
  146. }
  147. }
  148. return i;
  149. },
  150. };