節點操作
克隆節點
- node.cloneNode(deep)
- deep: 默認爲false
- deep 爲 true, 克隆元素及屬性,以及元素的內容和後代
- deep 爲 false, 只克隆元素本身,及它的屬性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
#box1 {
width: 100px;
height: 100px;
background: red;
border: 2px solid #000;
}
</style>
</head>
<body>
<div id="box">
<div id="box1">
<div>這是一個div</div>
</div>
</div>
<script>
{
let box = document.querySelector("#box");
let box1 = document.querySelector("#box1");
console.log(box1.cloneNode());
}
</script>
</body>
</html>
node.cloneNode(deep) 返回調用該方法的節點的一個副本.。
這裏打印的內容中並沒有拷貝“標籤內容”,因此小編這裏的版本默認值是false,即進行了淺拷貝(只克隆元素本身,及它的屬性。)。
注意:
在 DOM4 規範中(實現於Gecko 13.0(Firefox 13.0 / Thunderbird 13.0 / SeaMonkey 2.10)),deep是一個可選參數。如果省略的話,參數的默認值爲 true,也就是說默認是深度克隆。但在最新的規範裏,該方法的行爲已經改變了,其默認值變成了 false。
雖然該參數仍舊是可選的,但是溜_x_i_a_o_迪童鞋建議你必須要爲該方法設置 deep 參數,無論是爲了向前還是向後兼容考慮。
let box = document.querySelector("#box");
let box1 = document.querySelector("#box1");
box1.onclick =()=>{
alert(1);
}
box.appendChild(box1.cloneNode());
點擊沒有反應,因此溜_x_i_a_o_迪童鞋在這裏認爲淺克隆(克隆),是不能克隆事件的。
嘗試深克隆,發現內容進行了拷貝,但是事件不可進行拷貝。因此可得出結論,克隆始終不能克隆事件。
let box = document.querySelector("#box");
let box1 = document.querySelector("#box1");
box1.onclick =()=>{
alert(1);
}
box.appendChild(box1.cloneNode(true));
文檔碎片
很多小小白可能會這樣寫代碼,溜_x_i_a_o_迪童鞋並不建議你這樣做,因爲每加載一次循環都會導致頁面重新渲染一次,這樣會導致大大削減網頁的性能。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
#box div{
float: left;
width: 100px;
height: 100px;
background: red;
margin: 10px;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
{
let box = document.querySelector("#box");
for (let i = 0;i < 1000;i++){
box.innerHTML += `<div>${i}</div>`;
}
}
</script>
</body>
</html>
跟溜_x_i_a_o_迪童鞋一樣嫩的小白可能會這樣優化代碼:
let box = document.querySelector("#box");
let inner = "";
for (let i = 0;i < 1000;i++){
inner += `<div>${i}</div>`;
}
box.innerHTML = inner;
光看代碼可能無法直觀看出性能差異,我們可以做一下簡單的性能檢測
{
let box = document.querySelector("#box");
let inner = "";
console.time(1);
for (let i = 0;i < 1000;i++){
box.innerHTML += `<div>${i}</div>`;
}
console.timeEnd(1);
}
可以很直觀看出兩者性能的差異,希望咱們在開發過程中,還是多多思考有關性能優化的事情,這樣幾秒幾秒的累加,會使程序性能越發強大。
let box = document.querySelector("#box");
let inner = "";
console.time(1);
for (let i = 0;i < 1000;i++){
inner += `<div>${i}</div>`;
}
box.innerHTML = inner;
console.timeEnd(1);
用DOM的node.appendChild、document.createElement方法:
let box = document.querySelector("#box");
console.time(1);
for (let i = 0;i < 1000;i++){
let div = document.createElement("div");
div.innerHTML = i;
box.appendChild(div);
}
console.timeEnd(1);
我們發現與之前我們所做優化的性能是雷同的!
文檔碎片(性能優化)
DocumentFragments 是DOM節點。它們不是主DOM樹的一部分。通常的用例是創建文檔碎片,將元素附加到文檔碎片,然後將文檔碎片附加到DOM樹。在DOM樹中,文檔片段被其所有的子元素所代替。因爲文檔片段存在於內存中,並不在DOM樹中,所以將子元素插入到文檔片段時不會引起頁面迴流(對元素位置和幾何上的計算)。因此,使用文檔片段通常會帶來更好的性能。
let box = document.querySelector("#box");
console.time(1);
let fragment = document.createDocumentFragment(); // 文檔碎片
for(let i = 0; i < 1000; i++){
let div = document.createElement("div");
div.innerHTML = i;
fragment.appendChild(div); // 先把div放入文檔碎片裏
}
box.appendChild(fragment); // 最後把文檔碎片放入DOM中
console.timeEnd(1);
我們可以法此時速度更快了,性能最優!
注意:
可能不能的配置的電腦,運行速度都會有差異,並且每次運行時間都有可能不一樣,所以各位和小編一樣小白的夥計們,不用太在意!
(後續待補充)