cloneした要素を繰り返し使い回すようなコード書こうとして、なぜか .append() しても 1個しかでない。2回以上使い回せない!という状況になり、改めて使い方を確認してみたのでそれをメモしておきます。
要素を変数に入れて .appendTo()
まずは基本から。 .clone() せずに 要素を変数にいれて .appendTo()してみます。
利用したHTML
<div id="demo#" class="demoBlock">
<p class="btn-alert"><button>alert</button></p>
<p class="btn-clone"><button>clone</button></p>
<div class="clone-block"></div>
</div>
サンプル1 JavaScript
var $cloneElem1 = $('#demo1 .btn-alert');
$('#demo1').on('click', '.btn-clone', function(){
$cloneElem1.appendTo('#demo1 .clone-block');
});
$('#demo1 .btn-alert').on('click', function(){
alert('click!');
});
サンプル1(要素を変数に入れて .appendTo())
要素を変数にいれただけでそれを .appendTo() した場合は、場所が入れ替わるだけになります。
.clone() した要素を変数に
そこで要素を .clone()
してから .appendTo() します。
.clone() | jQuery API Documentation
まずは変数に入れる時点で .clone()
してみます
サンプル2 JavaScript
var $cloneElem2 = $('#demo2 .btn-alert').clone();
$('#demo2').on('click', '.btn-clone', function(){
$cloneElem2.appendTo('#demo2 .clone-block');
});
$('#demo2 .btn-alert').on('click', function(){
alert('click!');
});
サンプル2( .clone() した要素を変数に)
しかし、この場合は変数に格納された .clone() されたものが .appendTo() されるだけなので、動作としてはサンプル1と変わらず。
.appendTo() 直前に .clone()
冷静に考えたらわかるはずなのに、なぜかすぐに思いつかなかったこの方法。ボタンを押したタイミングで変数に入れた要素を .clone() で複製してその複製を .appendTo() することで何度も複製が動作するようになります。
サンプル3 JavaScript
var $cloneElem3 = $('#demo3 .btn-alert');
$('#demo3').on('click', '.btn-clone', function(){
$cloneElem3.clone(true).appendTo('#demo3 .clone-block');
});
$('#demo3 .btn-alert').on('click', function(){
alert('click!');
});
サンプル3(複製もされてアラートされる)
.clone() の引数に true
を渡すと、要素に付いているイベントやdataなども全部まるっとcloneしてくれます。
イベントをデリゲート系でかいておく
true 引数を渡さずともアラートさせる方法もあります。
複製した要素でもアラートさせるために、アラートのクリックのイベントもデリゲート系のイベントとしてコードを書いておく方法です。
サンプル4 JavaScript
var $demo4 = $('#demo4'),
$cloneElem4 = $demo4.find('.btn-alert');
$demo4.on('click', '.btn-clone', function(){
$cloneElem4.clone().appendTo('#demo4 .clone-block');
});
$demo4.on('click', '.btn-alert', function(){
alert('click!');
});
サンプル4(cloneボタン用のデリゲートイベント)
余談: .clone() した要素を .clone()
変数に .clone() した要素をいれておき、 さらに .appendTo() するときに、その .clone() した要素を .clone()してみます。
引数も true をいれておいてみます。
サンプル5 JavaScript
var $cloneElem5 = $('#demo5 .btn-alert').clone(true);
$('#demo5').on('click', '.btn-clone', function(){
$cloneElem5.clone(true).appendTo('#demo5 .clone-block');
});
$('#demo5 .btn-alert').on('click', function(){
alert('click!');
});
サンプル5( .clone() を .clone() )
この場合、引数に true を渡していたとしても、イベントが動作しません。
サンプル4のように、こちらもデリゲート系のイベントをつけておけば .clone() の .clone() でも イベントが動作します。
ちょっとした余談でした。