0Pricing
HTML Academy · レッスン

cloneNodeでテンプレートを複製する

cloneNode(true)でテンプレートのコンテンツを効率的に複製します

「cloneNodeでテンプレートを複製する」はCoddyKit上の無料HTML Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはHTML Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 HTML Academyコースには全4レッスンが含まれています。

深いクローンと浅いクローン

cloneNodeメソッドは、boolean型の引数を受け取ります。

const template = document.getElementById('card-tmpl');

// Deep clone (true): copies all descendants
const deep = template.content.cloneNode(true);

// Shallow clone (false): only the root node, no children
const shallow = template.content.cloneNode(false);
// shallow has no children — use deep for templates

1つのtemplateから複数の要素を生成する

templateは何回でもクローンできます。

const tmpl = document.getElementById('item-tmpl');
const container = document.getElementById('list');

['Alpha', 'Beta', 'Gamma'].forEach((name, i) => {
  const clone = tmpl.content.cloneNode(true);
  clone.querySelector('.item-name').textContent = name;
  clone.querySelector('.item-num').textContent = i + 1;
  container.appendChild(clone);
});
// 3 separate clones — modifying one doesn't affect others

DocumentFragmentとパフォーマンス

パフォーマンス向上のため、DocumentFragmentを使ってDOMの更新をまとめて行います。

const frag = document.createDocumentFragment();
const tmpl = document.getElementById('row-tmpl');

rows.forEach(row => {
  const clone = tmpl.content.cloneNode(true);
  // fill in clone...
  frag.appendChild(clone);
});

// ONE DOM append instead of many:
document.getElementById('table-body').appendChild(frag);
// Appending to a fragment doesn't trigger layout; append once for performance

クローンとイベントリスナー

元のtemplateに設定したイベントリスナーはコピーされません。

// Template definition:
const tmpl = document.getElementById('btn-tmpl');
const origBtn = tmpl.content.querySelector('.btn');
origBtn.addEventListener('click', () => console.log('click'));

// Clone:
const clone = tmpl.content.cloneNode(true);
const cloneBtn = clone.querySelector('.btn');
// cloneBtn does NOT have the click listener!
// You must re-add listeners after cloning

クローン後にリスナーを追加する

クローンした後にイベントを設定します。

function createCard(data) {
  const clone = document.getElementById('card-tmpl').content.cloneNode(true);

  const deleteBtn = clone.querySelector('.delete-btn');
  deleteBtn.addEventListener('click', () => deleteItem(data.id));

  clone.querySelector('.title').textContent = data.title;

  return clone;  // return the fragment
}

document.getElementById('list').appendChild(createCard(item));

importNodeを使う

document.importNodeはcloneNodeの代替手段です。

const tmpl = document.getElementById('card-tmpl');

// Equivalent to tmpl.content.cloneNode(true):
const clone = document.importNode(tmpl.content, true);
// importNode adopts the node into the current document
// In the same document, this is functionally identical to cloneNode

templateのスロットの概要

Web Componentsでは、名前付きスロットを使ってtemplateにコンテンツを挿入します。

<template id="card-tmpl">
  <div class="card">
    <slot name="title">Default Title</slot>
    <slot name="body">Default body text.</slot>
  </div>
</template>
<!-- slot elements become placeholders for projected content -->
<!-- Covered in full in the Shadow DOM course -->

クローンしたコンテンツを更新する

クローンしたtemplateのコンテンツに値を設定する方法です。

const clone = tmpl.content.cloneNode(true);

// textContent — safe, no HTML parsing:
clone.querySelector('.name').textContent = user.name;

// innerHTML — only if content is trusted:
clone.querySelector('.bio').innerHTML = trustedHTML;

// setAttribute:
clone.querySelector('.avatar').src = user.avatar;
clone.querySelector('.profile-link').href = `/users/${user.id}`;

document.createElementとの比較

繰り返し項目を作成する場合のtemplateとcreateElementを比較します。

// createElement: verbose for complex structures
const card = document.createElement('div');
card.className = 'card';
const title = document.createElement('h2');
card.appendChild(title);
// ... many lines for nested structure

// template: define once, clone efficiently
const clone = tmpl.content.cloneNode(true);
// Complex structure defined in HTML once
// Clone is fast and the template handles nesting

メモリとtemplate

templateのメモリ上での動作:

  • templateはDocumentFragmentとしてメモリに保持されます
  • クローンは独立したコピーであり、DOMから削除されるとGCの対象になります
  • DOM要素が存在する限り、template自体は保持されます
  • 動的なtemplateでは、関数の外側でtemplateへの参照をキャッシュします

ブラウザーの対応状況

template要素の対応状況:

  • 2014年頃以降、すべてのモダンブラウザーで対応しています
  • IEには対応していません(IEはサポート終了済みです)
  • モダンなプロジェクトではポリフィルは必要ありません

確認問題

templateをクローンした後、イベントリスナーを再追加する必要があるのはなぜですか?

まとめ:cloneNode

cloneNodeの要点:

  • cloneNode(true) — すべての子孫を含む深いコピーを作成します
  • イベントリスナーはコピーされないため、クローン後に再設定します
  • パフォーマンス向上のため、DocumentFragmentを使って追加をまとめます
  • レンダリングループの外側でtemplateへの参照をキャッシュします
  • 安全にテキストを挿入するにはtextContentを使います

よくある質問

「cloneNodeでテンプレートを複製する」レッスンは無料ですか?

はい。「cloneNodeでテンプレートを複製する」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、HTML Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 HTML Academyコースには全4レッスンが含まれています。

「cloneNodeでテンプレートを複製する」で何を学びますか?

cloneNode(true)でテンプレートのコンテンツを効率的に複製します ブラウザで直接実行するハンズオンコードでHTML Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

HTML Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのHTML Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「cloneNodeでテンプレートを複製する」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このHTML Academyレッスンでコードを書いて実行できますか?

はい。すべてのHTML Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. template要素と不活性コンテンツ
  2. cloneNodeでテンプレートを複製する
  3. JavaScriptによるレンダリングでtemplateを使う
  4. templateとinnerHTMLのセキュリティ
← HTML Academyに戻る