jQueryのclone()を考察する

2011.10.13 Author: ぴ

jQueryのclone()についてのお話です。

最近、clone()を使った実装を行う必要がありまして、私の想像とは違った動きをしていた部分がありました。
あくまでも「私の想像と」というのがミソで、閲覧いただいている方は「そんなの当たり前」と思われるかもしれませんが、その際はご容赦ください。

clone()は、バージョン1.5以上で2つの引数を設定することができます。マニュアルによれば、

.clone( [withDataAndEvents] )
.clone( [withDataAndEvents,] [deepWithDataAndEvents] )

といった使い方をするようです。

このwithDataAndEvents部分は、デフォルト値はfalseです。
そのため、単にcloneした場合にはイベントなどは一切引き継がれないことになります。
それは容易に理解できるのですが。

ここでは、cloneでフォーム要素を複製することを考えてみます。
フォーム要素は画面表示後にユーザーが操作できるのが基本です。
複製するタイミングが画面表示前であれば、何ら問題はなかったのです。

今回の要件は、ユーザーがフォーム要素を操作した任意のタイミングで複製をするというものでした。たとえば、プルダウンがあり初期状態が以下のようになっていたとします。

一応ソース:
<select id="target">
<option>ラベル1</option>
<option selected>ラベル2</option>
<option>ラベル3</option>
</select>
この状態でcloneを行えば、ラベル2が選択された状態で複製されます。何ら問題はないですね。

しかし、初期状態のラベル2の表示から、ラベル1やラベル3に変更したとします。
変更した状態で、clone()を実行すると、変更が引き継がれずに初期状態のラベル2が表示されたままとなってしまいました。

当初は、.clone(true)としなければいけないのだろうと思い、引数にtrueを入れてみたのですが、意図する結果となりませんでした。そういうものではないようです。

以下のような感じで回避しました。

var target = $('#target).clone().attr('id', 'target2').val($('#target :selected').val());
$('#target').after(target);
要は、オリジナルの設定値を複製先の設定値に後で反映させるというものですね。
あと細かいですが、html的に同一IDを持つのはよろしくありませんので、cloneと同時にIDも変更しています。

clone()を使う時には、気をつけてください。

名古屋のWebシステム開発・ネットワーク構築会社 コネクティボへ