Demo
replaceChild
首相想到的就是 replaceChild
使用,MDN 定義如下
定義
用指定的節(jié)點替換當(dāng)前節(jié)點的一個子節(jié)點题山,并返回被替換掉的節(jié)點。
語法
replacedNode = parentNode.replaceChild(newChild, oldChild);
cloneNode
有定義知道故痊,replaceChild
是可以用來替換 DOM 節(jié)點顶瞳,但僅限于同一父元素(或已知單個節(jié)點),不能直接實現(xiàn)不同級間的dom替換愕秫,所以用cloneNode
克隆下節(jié)點慨菱,下逐一替換
function changeDom(node1, node2) {
// 深度復(fù)制 DOM 節(jié)點,在 replace 替換
let clone1 = node1.cloneNode(true)
let clone2 = node2.cloneNode(true)
node1.parentNode.replaceChild(clone2, node1)
node2.parentNode.replaceChild(clone1, node2)
}
運行
HTML 如下
<div id="aa">div1
<span id="aa1"> span1</span>
</div>
<div id="bb">div2
<span id="bb1"> span2</span>
</div>
<div id="cc">
ccc
</div>
調(diào)用函數(shù)
changeDom(a, b1)
完善邏輯
那如果要 a
與 a1
互相替換呢戴甩,要知道他們是父子嵌套元素符喝,本身邏輯就會出現(xiàn)錯誤,所以應(yīng)提前判斷并在運行時拋出錯誤
判斷替換 DOM 節(jié)點是否為祖孫(嵌套)關(guān)系
// 判斷是否為子孫節(jié)點
function isInherit(node1, node2) {
while(node1.parentNode !== node2) {
node1 = node1.parentNode
if(node1.tagName == 'HTML') {
return false
}
}
return true
}
在完善 changDom
函數(shù)
function changeDom(node1, node2) {
if (node1 == node2) {
// 剔除替換為自己的
return new Error('Can\'t change to yourself!')
} else if (isInherit(node1, node2) || isInherit(node2, node1)) {
// 子孫關(guān)系不能替換
return new Error('Can\'t change by inherit Elements!')
} else {
// 深度復(fù)制 DOM 節(jié)點甜孤,在 replace 替換
let clone1 = node1.cloneNode(true)
let clone2 = node2.cloneNode(true)
node1.parentNode.replaceChild(clone2, node1)
node2.parentNode.replaceChild(clone1, node2)
}
}