jQuery:要素の変数格納と .clone() で複製

このエントリーをはてなブックマークに追加

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() でも イベントが動作します。

ちょっとした余談でした。