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 如下
<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>
调用函数
changeDom(a, b1)
完善逻辑
那如果要 a
与 a1
互相替换呢,要知道他们是父子嵌套元素,本身逻辑就会出现错误,所以应提前判断并在运行时抛出错误
判断替换 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)
}
}
网友评论