封装DOM,DOM是JS里面最常用的一个接口,单独使用比较麻烦,故封装起来使用,需要时调用

先介绍一种对象风格

对象风格

也叫命名空间风格
window.dom 是我们提供的全局对象
然后在dom上挂很多的函数

增删改查

注意:

  • 在index.html链接顺序中,dom.js要放在main.js文件上方才能优先访问到,封装的dom库在main.js文件中调用
  • 获取到的是否为伪数组,是否需要转换为数组,是否需要获取索引下标才能访问
  • 重点记忆需要变通的函数
    • each遍历
    • 获取元素
    • 修改style等 ```javascript window.dom = {
  1. //增
  2. create(string) { //用于创建新节点
  3. const container = document.createElement("template");
  4. container.innerHTML = string.trim();
  5. return container.content.firstChild;
  6. },
  7. after(node, node2) { //在node后面新增node2弟弟(变通式,利用现有insertBefore)
  8. node.parentNode.insertBefore(node2, node.nextSibling);
  9. },
  10. before(node, node2) { //在node前面新增node2哥哥(现有API)
  11. node.parentNode.insertBefore(node2, node)
  12. },
  13. append(parent, node) { //在parent内新增node儿子
  14. parent.appendChild(node)
  15. },
  16. wrap(node, parent) { //在node外新增parent爸爸(变通式)(会覆盖旧爸爸)
  17. dom.before(node, parent); //先让node成为parent的哥哥
  18. dom.append(parent, node); //再让node成为parent的儿子
  19. },
  20. //删
  21. remove(node) { //删除父亲指定下的儿子
  22. node.parentNode.removeChild(node)
  23. },
  24. empty(node) { //删除父亲名下所有儿子
  25. const array = [];
  26. let x = node.firstChild;
  27. while (x) {
  28. array.push(dom.remove(node.firstChild));
  29. x = node.firstChild //由于childNode元素会实时变化,因为儿子会发生替位关系,故针对每个大儿子删除,使用while循环不添加计数器
  30. }
  31. return array
  32. },
  33. //改
  34. attr(node, name, value) { //读&写 属性
  35. if (arguments.length === 3) { //重载(根据参数的不同写不同的代码)
  36. node.setAttribute(name, value) //现有API ,修改属性
  37. } else if (arguments.length === 2) {
  38. return node.getAttribute(name) //现有API , 获取属性
  39. }
  40. },
  41. text(node, string) { //读&写 文本内容
  42. if (arguments.length === 2) {
  43. if ('innerText' in node) { //适配
  44. node.innerText = string;
  45. } else {
  46. node.textContent = string;
  47. }
  48. } else if (arguments.length === 1) {
  49. if ('innerText' in node) { //适配
  50. return node.innerText
  51. } else {
  52. return node.textContent
  53. }
  54. }
  55. },
  56. html(node, string) { //读&写 html内容
  57. if (arguments === 2) {
  58. node.innerHTML = string;
  59. } else if (arguments.length === 1) {
  60. return node.innerHTML
  61. }
  62. },
  63. style(node, name, value) { //读&写 style
  64. if (arguments.length === 3) {
  65. // dom.style(div,'color','red')
  66. node.style[name] = value
  67. } else if (arguments.length === 2) {
  68. if (typeof name === 'string') {
  69. // dom.style(div,'color')
  70. return node.style[name]
  71. } else if (name instanceof Object) { //instanceof判断name是否为Object的实例,返回值为布尔值
  72. // dom.style(div,{color:'red'})
  73. const object = name;
  74. for (let key in object) { //遍历object,把object中所有未知的key声明且读到
  75. node.style[key] = object[key] //将object中所有 [key变量下的值] 存入node的style中key变量下
  76. }
  77. }
  78. }
  79. },
  80. class: { //读&写 class
  81. add(node, className) {
  82. node.classList.add(className)
  83. },
  84. remove(node, className) {
  85. node.classList.remove(className);
  86. },
  87. has(node, className) {
  88. return node.classList.contains(className) //记得return返回值得确认
  89. }
  90. },
  91. //改DOM事件
  92. on(node, eventName, fn) {
  93. node.addEventListener(eventName, fn)
  94. },
  95. off(node, eventName, fn) {
  96. node.removeEventListener(eventName, fn)
  97. },
  98. //查,用于获取元素(以上均用全局id)
  99. find(selector, scope) { //通过选择器和指定范围查找
  100. return (scope || document).querySelectorAll(selector) //存在第二个参数scope则在第二个参数的范围里查找,若无则在document中查找
  101. },
  102. parent(node) { //传入节点,返回节点的爸爸
  103. return node.parentNode
  104. },
  105. children(node) { //传入节点,返回节点的儿子
  106. return node.children
  107. },
  108. siblings(node) { //传入节点,返回兄弟姐妹元素
  109. return Array.from(node.parentNode.children).filter(n => n !== node) //得到的伪数组需要转换为数组才能使用filter接口,过滤其他元素,将这些元素存入数组并返回
  110. },
  111. next(node) { //传入节点,返回弟弟妹妹,排除文本节点
  112. let x = node.nextSibling
  113. while (x && x.nodeType === 3) { //x存在且x的节点类型为文本节点(同时也需排除x节点不存在的前提)
  114. x = x.nextSibling //若该节点属于文本节点,则遍历下个节点,直到元素节点再返回
  115. }
  116. return x
  117. },
  118. previous(node) { //传入节点,返回哥哥姐姐,排除文本节点
  119. let x = node.previousSibling
  120. while (x && x.nodeType === 3) {
  121. x = x.previousSibling
  122. }
  123. return x
  124. },
  125. each(nodeList, fn) { //对节点列表中的每一个节点遍历调用fn函数
  126. for (let i = 0; i < nodeList.length; i++) {
  127. fn.call(null, nodeList[i])
  128. }
  129. },
  130. index(node) { //传入节点,获取节点的索引
  131. const list = dom.children(node.parentNode) //遍历其父亲的所有孩子,纳入一个列表
  132. let i //注意此处i声明在函数外,以便return
  133. for (i = 0; i < list.length; i++) {
  134. if (list[i] === node) {
  135. break
  136. }
  137. }
  138. return i
  139. }

} ```