Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions files/en-us/web/api/document/importnode/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ currently in the document tree.
Unlike {{domxref("document.adoptNode()")}}, the original node is not removed from its
original document. The imported node is a clone of the original.

**`importNode()`** will cause the `document` to immediately adopt the node, in contrast
with {{domxref("Node.cloneNode()#return_value", "Node.cloneNode()")}} which will not
cause the `document` to adopt the node until it is inserted into the document. This makes
**`importNode()`** ideal for working with the {{htmlelement("template")}} element.

## Syntax

```js-nolint
Expand Down
2 changes: 1 addition & 1 deletion files/en-us/web/api/htmltemplateelement/content/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ A {{domxref("DocumentFragment")}}.

```js
const templateElement = document.querySelector("#foo");
const documentFragment = templateElement.content.cloneNode(true);
const documentFragment = document.importNode(templateElement.content, true);
```

## Specifications
Expand Down
2 changes: 1 addition & 1 deletion files/en-us/web/api/node/clonenode/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Additionally, for a {{HTMLElement("canvas")}} element, the painted image is not
> Also, `name` attributes may need to be modified,
> depending on whether duplicate names are expected.

To clone a node to insert into a _different_ document, use
To clone a node to insert into a _different_ document, or when cloning a {{htmlelement("template")}} element, use
{{domxref("Document.importNode()")}} instead.

## Syntax
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ customElements.define(
let templateContent = template.content;

const shadowRoot = this.attachShadow({ mode: "open" });
shadowRoot.appendChild(templateContent.cloneNode(true));
shadowRoot.appendChild(document.importNode(templateContent, true));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For cases like this, I think it's actually fine to use cloneNode because it's immediately appended, no?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be fine, but IMO it's a lot easier to be consistent and use importNode everywhere.

}
},
);
```

The key point to note here is that we append a clone of the template content to the shadow root, created using the {{domxref("Node.cloneNode()")}} method.
The key point to note here is that we append a clone of the template content to the shadow root, created using the {{domxref("Document.importNode()")}} method.

And because we are appending its contents to a shadow DOM, we can include some styling information inside the template in a {{htmlelement("style")}} element, which is then encapsulated inside the custom element.
This wouldn't work if we just appended it to the standard DOM.
Expand Down Expand Up @@ -255,7 +255,7 @@ customElements.define(
"element-details-template",
).content;
const shadowRoot = this.attachShadow({ mode: "open" });
shadowRoot.appendChild(template.cloneNode(true));
shadowRoot.appendChild(document.importNode(template, true));
}
},
);
Expand Down
10 changes: 5 additions & 5 deletions files/en-us/web/html/reference/elements/template/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ There are two main ways to use the `<template>` element.

By default, the element's content is not rendered.
The corresponding {{domxref("HTMLTemplateElement")}} interface includes a standard {{domxref("HTMLTemplateElement.content", "content")}} property (without an equivalent content/markup attribute). This `content` property is read-only and holds a {{domxref("DocumentFragment")}} that contains the DOM subtree represented by the template.
This fragment can be cloned via the {{domxref("Node.cloneNode", "cloneNode")}} method and inserted into the DOM.
This fragment can be cloned via either the {{domxref("Document.importNode()", "importNode")}} or the {{domxref("Node.cloneNode", "cloneNode")}} method and inserted into the DOM.

Be careful when using the `content` property because the returned `DocumentFragment` can exhibit unexpected behavior.
For more details, see the [Avoiding DocumentFragment pitfalls](#avoiding_documentfragment_pitfalls) section below.
Expand Down Expand Up @@ -109,15 +109,15 @@ if ("content" in document.createElement("template")) {
const template = document.querySelector("#productrow");

// Clone the new row and insert it into the table
const clone = template.content.cloneNode(true);
const clone = document.importNode(template.content, true);
let td = clone.querySelectorAll("td");
td[0].textContent = "1235646565";
td[1].textContent = "Stuff";

tbody.appendChild(clone);

// Clone the new row and insert it into the table
const clone2 = template.content.cloneNode(true);
const clone2 = document.importNode(template.content, true);
td = clone2.querySelectorAll("td");
td[0].textContent = "0384928528";
td[1].textContent = "Acme Kidney Beans 2";
Expand Down Expand Up @@ -280,11 +280,11 @@ function clickHandler(event) {
event.target.append(" — Clicked this div");
}

const firstClone = template.content.cloneNode(true);
const firstClone = document.importNode(template.content, true);
firstClone.addEventListener("click", clickHandler);
container.appendChild(firstClone);

const secondClone = template.content.cloneNode(true);
const secondClone = document.importNode(template.content, true);
secondClone.children[0].addEventListener("click", clickHandler);
container.appendChild(secondClone);
```
Expand Down