JS - 替换DOM节点

Demo

replaceChild

首相想到的就是 replaceChild 使用,MDN 定义如下

定义

用指定的节点替换当前节点的一个子节点,并返回被替换掉的节点。

语法
replacedNode = parentNode.replaceChild(newChild, oldChild);

cloneNode

有定义知道,replaceChild是可以用来替换 DOM 节点,但仅限于同一父元素(或已知单个节点),不能直接实现不同级间的dom替换,所以用cloneNode 克隆下节点,下逐一替换

  function changeDom(node1, node2) {
      // 深度复制 DOM 节点,在 replace 替换                
      let clone1 = node1.cloneNode(true)
      let clone2 = node2.cloneNode(true)

      node1.parentNode.replaceChild(clone2, node1)
      node2.parentNode.replaceChild(clone1, node2)
  }

运行

HTML 如下

  
div1 span1
div2 span2
ccc

调用函数

     changeDom(a, b1)

完善逻辑

那如果要 aa1 互相替换呢,要知道他们是父子嵌套元素,本身逻辑就会出现错误,所以应提前判断并在运行时抛出错误

判断替换 DOM 节点是否为祖孙(嵌套)关系

  // 判断是否为子孙节点
  function isInherit(node1, node2) {
    while(node1.parentNode !== node2) {
      node1 = node1.parentNode
      if(node1.tagName == 'HTML') {
        return false
      }
    }
    return true
  }

在完善 changDom 函数

  function changeDom(node1, node2) {
    if (node1 == node2) {       
      // 剔除替换为自己的
      return new Error('Can\'t change to yourself!')
    } else if (isInherit(node1, node2) || isInherit(node2, node1)) {
      // 子孙关系不能替换
      return new Error('Can\'t change by inherit Elements!')
    } else {    
      // 深度复制 DOM 节点,在 replace 替换                
      let clone1 = node1.cloneNode(true)
      let clone2 = node2.cloneNode(true)

      node1.parentNode.replaceChild(clone2, node1)
      node2.parentNode.replaceChild(clone1, node2)
    }
  }

你可能感兴趣的:(JS - 替换DOM节点)