この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:5
ページ更新者:T
更新日時:2026-06-11 07:12:00

タイトル: 要素のコピー
SEOタイトル: jQuery で要素をコピーする方法(clone / clone(true) でイベント込み複製 / appendTo / 動的フォーム追加 / vanilla JS cloneNode との比較)

この記事の要点
  • jQuery で要素を複製するには $(selector).clone() を使う
  • clone()イベントハンドラやデータをコピーしないのが既定。コピーするには clone(true)
  • 複製後は appendTo() / prependTo() / before() / after() でどこに挿入するかを指定する
  • id 属性もそのまま複製されるため、ID 重複に注意 — 複製後に書き換えるかクラスベースに設計する
  • 純粋 JS なら Node.cloneNode(true)。SPA / モダン開発では vanilla JS で十分なケースも多い

jQuery clone() の基本

clone() は jQuery オブジェクトをディープコピーするメソッドです。元の要素を残したまま同じ HTML 構造を複製し、appendTo などで好きな場所に挿入できます。動的なフォーム追加、リスト項目の追加 UI などに頻出する基本機能です。

HTML

<div id="item_list">
  <input id="item" type="text">
</div>

<input type="button" onclick="copyItem()" value="コピーボタン">

上記の <input id="item"> をコピーする例です。

jQuery 実装

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
function copyItem() {
  $("#item").clone().appendTo("#item_list");
}
</script>

clone() でコピー、appendTo()#item_list の末尾に追加しています。これだけで「ボタンを押すたびに input が増える」ような動的フォームを実現できます。

clone() と clone(true) の違い

呼び方イベントハンドラdata()用途
clone()コピーしないコピーしないHTML 構造のみ複製
clone(true)コピーするコピーするイベント込みで複製
clone(true, true)コピー + 子孫もコピー + 子孫も完全な深いコピー
// 例: クリックイベント付きボタンを複製
$(&quot;#origBtn&quot;).on(&quot;click&quot;, function() {
  alert(&quot;クリックされた!&quot;);
});

$(&quot;#origBtn&quot;).clone().appendTo(&quot;body&quot;);
// コピー先のボタンを押しても何も起きない

$(&quot;#origBtn&quot;).clone(true).appendTo(&quot;body&quot;);
// コピー先のボタンも同じアラートが出る

挿入位置の指定

メソッド挿入位置
appendTo(parent)親の末尾(子要素として)
prependTo(parent)親の先頭
insertAfter(target)対象の直後(同階層)
insertBefore(target)対象の直前
$(&quot;#item&quot;).clone().insertAfter(&quot;#item&quot;);          // 同じ階層、直後
$(&quot;#card&quot;).clone().prependTo(&quot;#list&quot;);            // リスト先頭に
$(&quot;#row&quot;).clone().insertBefore(&quot;#footerRow&quot;);     // フッター行の前に

ID 重複の罠

HTML の id 属性はドキュメント内で一意であるべきですが、clone() は属性をそのまま複製するため同じ id を持つ要素が複数できてしまいます。

// NG: 2 つの #item ができてしまう
$(&quot;#item&quot;).clone().appendTo(&quot;#item_list&quot;);

// OK: id を書き換える
let count = $(&quot;#item_list input&quot;).length;
$(&quot;#item&quot;)
  .clone()
  .attr(&quot;id&quot;, &quot;item_&quot; + count)         // id を一意化
  .removeAttr(&quot;name&quot;)                  // 必要に応じて
  .val(&quot;&quot;)                             // 値クリア
  .appendTo(&quot;#item_list&quot;);

// よりベストプラクティス: ID ではなくクラスで設計
$(&quot;.item&quot;).first().clone().appendTo(&quot;#item_list&quot;);

動的フォーム追加の完全例

<div id="form-rows">
  <div class="row">
    <input type="text" name="items[]" placeholder="商品名">
    <input type="number" name="qty[]" placeholder="数量">
    <button type="button" class="remove">削除</button>
  </div>
</div>
<button type="button" id="addRow">行を追加</button>
$(function() {
  // 行追加
  $("#addRow").on("click", function() {
    const $row = $("#form-rows .row").first().clone();
    $row.find("input").val("");      // 値をクリア
    $row.appendTo("#form-rows");
  });

  // 行削除(イベント委譲)
  $("#form-rows").on("click", ".remove", function() {
    if ($("#form-rows .row").length > 1) {
      $(this).closest(".row").remove();
    }
  });
});

イベント委譲(on("click", ".remove", ...))を使えば、後から追加された行の削除ボタンにも自動でイベントが効きます。これと clone() を組み合わせるのが動的フォームの王道パターン。

外す系メソッドとの関係

メソッド挙動
clone()元を残してコピー
detach()DOM から外すが内部のデータ / イベントは保持
remove()DOM から削除、データもクリア
empty()子要素のみ削除

純粋な JavaScript(vanilla)での書き方

jQuery を使わない場合、Node.cloneNode(true) で同等の処理ができます。モダンブラウザではこれで十分なケースも多い。

function copyItem() {
  const orig = document.getElementById(&quot;item&quot;);
  const copy = orig.cloneNode(true);   // true で子孫もコピー
  copy.removeAttribute(&quot;id&quot;);          // ID 重複回避
  copy.value = &quot;&quot;;
  document.getElementById(&quot;item_list&quot;).appendChild(copy);
}
項目jQuery clonecloneNode
子孫も複製常に深い引数 true で深い
イベントもコピーclone(true) で可cloneNode は不可(手動で設定)
jQuery 依存ありなし(標準 DOM API)

パフォーマンスの注意

  • 巨大な DOM を頻繁に clone するとメモリと描画コストが大きい
  • 追加が大量にあるならDocumentFragment を使ってまとめて挿入(vanilla JS の場合)
  • 頻繁な DOM 追加削除は仮想 DOM フレームワーク(React / Vue)の方が効率的

FAQ

Q: clone() でイベントが効かない
A: 既定の clone() はイベントをコピーしません。clone(true) を使うか、イベント委譲($(parent).on(&quot;click&quot;, &quot;.child&quot;, ...))で解決します。後者の方がメモリ効率が良いです。

Q: フォームの value がコピーされない
A: ブラウザによっては input の値属性と value プロパティが別扱い。コピー後に .val("") でクリアしたり、.val(orig.val()) で改めて設定するのが安全。

Q: jQuery を使わずに同じことをしたい
A: element.cloneNode(true) + parent.appendChild() で同等です。イベントは addEventListener で都度設定。

関連

  • jQuery — DOM 操作を簡潔にするライブラリ
  • appendTo / prependTo — 要素の追加
  • on — イベントハンドラの設定(委譲も対応)
  • cloneNode — 純粋 JS の DOM 複製 API
  • DocumentFragment — 一括挿入の高速化