Node: phương thức cloneNode()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
Phương thức cloneNode() của giao diện Node trả về một bản sao của nút mà phương thức này được gọi trên đó. Đối số của nó điều khiển việc cây con chứa trong nút có được sao chép hay không.
Theo mặc định, việc sao chép một nút sẽ sao chép tất cả các thuộc tính và giá trị của chúng, bao gồm cả các trình xử lý sự kiện được chỉ định qua thuộc tính. Nếu đặt tham số deep, bạn cũng có thể sao chép cây con chứa trong nút. Nó không sao chép bất kỳ dữ liệu nội bộ nào khác, chẳng hạn các trình xử lý sự kiện được thêm bằng addEventListener() hoặc các thuộc tính onevent (ví dụ node.onclick = someFunction), hay hình ảnh đã được vẽ sẵn của phần tử <canvas>.
Phương thức Document.importNode() cũng tạo một bản sao của nút. Khác biệt là importNode() sao chép nút trong ngữ cảnh của tài liệu gọi, còn cloneNode() dùng tài liệu của chính nút đang được sao chép. Ngữ cảnh tài liệu sẽ quyết định CustomElementRegistry dùng để dựng mọi phần tử tùy chỉnh. Vì lý do này, để sao chép nút để dùng trong tài liệu khác, hãy dùng importNode() trên tài liệu đích. HTMLTemplateElement.content thuộc về một tài liệu riêng, vì vậy nó cũng nên được sao chép bằng document.importNode() để các phần tử tùy chỉnh con được dựng bằng định nghĩa trong tài liệu hiện tại.
Warning:
cloneNode() có thể dẫn đến các ID phần tử trùng lặp trong tài liệu! Nếu nút gốc có thuộc tính id, và bản sao sẽ được đặt trong cùng một tài liệu, thì bạn nên sửa id của bản sao để nó là duy nhất.
Ngoài ra, các thuộc tính name cũng có thể cần được sửa đổi, tùy thuộc vào việc tên trùng lặp có được mong đợi hay không.
Cú pháp
cloneNode()
cloneNode(deep)
Tham số
deepOptional-
Nếu là
true, thì nút và toàn bộ cây con của nó, bao gồm cả văn bản có thể nằm trong các nútTextcon, cũng sẽ được sao chép.Nếu là
falsehoặc bị bỏ qua, chỉ nút sẽ được sao chép. Cây con, bao gồm cả văn bản mà nút chứa, sẽ không được sao chép.Lưu ý rằng
deepkhông có tác dụng với phần tử void, chẳng hạn như các phần tử<img>và<input>.
Giá trị trả về
Nút Node mới được sao chép.
Nút được sao chép không có cha và không thuộc về tài liệu,
cho đến khi nó được thêm vào một nút khác thuộc tài liệu, bằng
Node.appendChild() hoặc phương thức tương tự.
Ví dụ
>Dùng cloneNode()
const p = document.getElementById("para1");
const p2 = p.cloneNode(true);
Dùng cloneNode() với template
Tránh dùng cloneNode() trên nội dung của phần tử <template>, vì nếu template chứa các phần tử tùy chỉnh, chúng sẽ không được nâng cấp cho đến khi được chèn vào tài liệu.
class MyElement extends HTMLElement {
constructor() {
super();
console.log("MyElement created");
}
}
customElements.define("my-element", MyElement);
const template = document.createElement("template");
template.innerHTML = `<my-element></my-element>`;
const clone = template.content.cloneNode(true);
// Chưa log gì; my-element chưa được định nghĩa trong tài liệu của template
customElements.upgrade(clone);
// Vẫn chưa log gì; my-element vẫn chưa được định nghĩa trong tài liệu của template
document.body.appendChild(clone);
// Log "MyElement created"; my-element giờ đã được nâng cấp
Thay vào đó, hãy dùng document.importNode() để sao chép nội dung template, để mọi phần tử tùy chỉnh được nâng cấp bằng các định nghĩa trong tài liệu hiện tại:
const clone = document.importNode(template.content, true);
// Log "MyElement created"; my-element được nâng cấp bằng các định nghĩa của document
document.body.appendChild(clone);
Thông số kỹ thuật
| Specification |
|---|
| DOM> # ref-for-dom-node-clonenode①> |