- append()とappendTo()は同じ動きではありません
- 誰が主体のメソッドなのか
- 戻り値の違いが重要
- 複数要素に追加したときの挙動
- DOMの本来の動き
- よくある混乱
- どちらを使うべきか
- パフォーマンスの差はあるのか
- 注意点:イベントの消失
- まとめ
append()とappendTo()は同じ動きではありません
jQueryで要素を追加するとき、次の2つの書き方があります。
$('#list').append('<li>Apple</li>'); $('<li>Apple</li>').appendTo('#list');
画面結果は同じです。だから「どっちでもいい」と思われがちです。しかし結論から言うと、この2つは操作対象が逆です。そしてこの違いは、チェーン処理や複数要素操作で大きな差になります。
誰が主体のメソッドなのか
まず整理します。
- append():親要素が主体
- appendTo():追加する要素が主体
appendは「ここに追加して」と親に命令しています。一方appendToは「自分をそこに入れて」と子が移動しています。
この違いが戻り値に影響します。
戻り値の違いが重要
jQueryはメソッドチェーンが前提です。ここで差が出ます。
var result = $('#list').append('<li>Apple</li>');
resultは#listです。つまり親要素が返ります。
一方、
var result = $('<li>Apple</li>').appendTo('#list');
こちらは追加されたli要素が返ります。
この違いはスタイル適用で顕著です。
$('#list').append('<li>Apple</li>').addClass('active');
activeはulに付きます。liではありません。
appendToなら違います。
$('<li>Apple</li>').appendTo('#list').addClass('active');
liにクラスが付きます。
複数要素に追加したときの挙動
さらに重要なのが複数要素です。
$('.list').append('<li>Apple</li>');
.listが3つあると、3箇所にliが追加されます。しかし同じliが移動するのではなく、jQueryが内部でクローンを生成します。
appendToでも同様ですが、戻り値が異なります。appendToは最後に追加された要素集合を返します。ここを理解していないと、イベント登録が意図した要素に付かないことがあります。
DOMの本来の動き
本来DOMでは、ノードは1か所にしか存在できません。
parent1.appendChild(node); parent2.appendChild(node);
この場合nodeは移動します。コピーではありません。jQueryは使いやすさのため、必要に応じてclone()を内部実行しています。
よくある混乱
テンプレートを使う場合です。
var item = $('<li class="item"></li>'); $('.list').append(item);
複数listがあると、最後のlistにしか残りません。なぜなら同一ノードが移動しているからです。文字列HTMLと違い、DOMオブジェクトは複製されません。
解決はcloneです。
$('.list').append(item.clone());
どちらを使うべきか
選択基準は「その後に何をしたいか」です。
- 親要素を操作したい → append
- 追加した要素を操作したい → appendTo
特にイベント登録やアニメーションを直後に行う場合、appendToの方が自然になります。
パフォーマンスの差はあるのか
基本的に差はほぼありません。どちらも内部ではappendChildを使います。違いはAPI設計です。
ただし大量追加ではHTML文字列のappendが最も高速です。DOM生成回数が減るためです。
注意点:イベントの消失
cloneを伴う場合、イベントハンドラはコピーされません(deepコピーを指定しない限り)。
item.clone(true);
これを知らないと「追加した要素だけクリックできない」現象が起きます。
まとめ
appendとappendToは機能が同じに見えますが、考え方が逆です。
- append:コンテナ中心の思考
- appendTo:要素中心の思考
jQueryはDOM操作を文章のように書けることが特徴でした。この2つのメソッドは、その読みやすさのための設計です。違いを理解すると、チェーン処理や動的UIのコードが意図通りに動くようになります。