THE HAM MEDIA BLOG

続 jQueryメモ:変数に入っているのは?

Clip to Evernote このエントリーをはてなブックマークに追加
カテゴリ:
jQuery
タグ:
jquery
変数

まだまだ勉強不足

昨日「jQueryメモ:変数に入れた要素が・・・」というエントリーを書いたのですが、そのlivedoorクリップのコメントにて、二人の方からご指摘を受けましたので、再度お勉強。



livedoor clipにて

こんなご指摘をうけました。

コピーしたけりゃclone()だろうねぇ。普通は

livedoor クリップ @mattz

というご指摘と、もう一つ

変数arrangeに何が入っているのか全く分かってないでしょorz
jQueryのコードを読んでる点はほめるべきだとおもふ。

#最初のコードだと、jQueryオブジェクトを入れてるから、移動するんだよね。んで、次のコードではJQueryオブジェクトじゃなくてhtml要素を入れてるからコピーになる。
#cloneとか無かったっけ、jQueryって?
#ま、ここはチラシの裏

livedoor クリップ @Arc Cosine

なるほど、勉強になります!
と思ったけど、聞いても実際にやってみないことには覚えられない自分は、それらについてもとりあえず調べてみました。

変数に何が入っているか

まずは変数に何が入っているかを知らねばならぬ!と思ったので考えてみた。

■サンプルHTML

<ul id="test0">
  <li class="test-id1">テスト1</li>
  <li class="test-id2">テスト2</li>
  <li class="test-id3">テスト3</li>
  <li class="test-id4">テスト4</li>
  <li class="test-id5">テスト5</li>
</ul>

先日使ったものと同じHTMLを再利用。

■サンプルスクリプト

var arrange = $('#test0 li');
$('button#btn1').one('click',function(){
	alert(arrange);
});

■サンプルデモ

  • テスト1
  • テスト2
  • テスト3
  • テスト4
  • テスト5

ボタンをクリックすると、変数がアラートします。これをFirefoxなんかでアラートさせると、「[object Object]」というのが出てきます。

これではどういうのかわかりにくいので、Firebugで表示させるように、console.log()を使って中身を見てみることに。すると、

[li.test-id1, li.test-id2, li.test-id3, li.test-id4, li.test-id5]

というのが表示されました。コメントによると、これがjQueryオブジェクトってことですね。

それぞれliの中身をみてみると、その要素丸々が表示される。おそらくイメージとしては、変数の中にすでに代入されているというよりは、その部分を指し示しているというイメージに近いと思う。

変数に何が入っているか その2

ではもう一方のhtml()を使ってみたのはどんな変数になっているか。

■サンプルスクリプト

var arrange2 = $('#test2').html();
$('button#btn2').one('click',function(){
	alert(arrange2);
});

■サンプルデモ

  • テスト1
  • テスト2
  • テスト3
  • テスト4
  • テスト5

これもご指摘されたとおり。HTMLがそのまま入っている。さっきとの違いは、指し示されているのじゃなくて、今度は変数の中にHTMLが入っているってイメージでいいと思う。イメージでの違いは、変数の中に何かが入っているのか、それとも変数が何かを指し示しているか、そんな違いだと思う。(あくまで個人的イメージでの捉え方なので、違うぞおんどりゃ〜というご指摘があればお願いします。)

この違いによるhtml()での書き出し

これらのことから、ご指摘をいただいたように、この違いのある変数をhtml()で表示させると、前者は指し示している部分の要素が指定した場所へ移動して、後者は変数自体にHTMLがコピーされて入っているから、移動ではなくコピーされるってことなんだと思う。

今までは大体の感覚でこれらを使っていましたが、ある程度今回のでイメージできました。

clone()

それでは、もう一つのご指摘だった、clone()を使うのが普通ですよ〜って部分。まずは本体のclone()部分を見てみよう。

jQuery.fn = {
clone: function( events ) {
  var ret = this.map(function(){
    if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
      var clone = this.cloneNode(true),
        container = document.createElement("div");
      container.appendChild(clone);
      return jQuery.clean([container.innerHTML])[0];
    } else
      return this.cloneNode(true);
  });

  var clone = ret.find("*").andSelf().each(function(){
    if ( this[ expando ] !== undefined )
      this[ expando ] = null;
  });

  if ( events === true )
    this.find("*").andSelf().each(function(i){
      if (this.nodeType == 3)
        return;
      var events = jQuery.data( this, "events" );

      for ( var type in events )
        for ( var handler in events[ type ] )
          jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
    });

  return ret;
}
};

では、これをどう使うのか?次に調べてみた。

なるほど、これなら昨日のhtml()とclone()を入れ替えるだけでどうなるかわかる。

cloneを使ってみる

とりあえずアラートさせてみます。

■サンプルデモ

  • テスト1
  • テスト2
  • テスト3
  • テスト4
  • テスト5

変数にjQueryオブジェクトを入れたのと同じように、「[object Object]」が表示されます。console.log()でみても、 [li.test-id1, li.test-id2, li.test-id3, li.test-id4, li.test-id5]と、同じですね。

しかし、先程と違うのは、cloneは複製だということ。変数に直接jQueryオブジェクトを指定しただけだと、さっきみたいに、htmlを示しているようなイメージなのですが、cloneは、そのjQueryオブジェクトごと複製のためにコピーしてしまっているというイメージなんだと思います。

実際に動作させたデモを見てみましょう。

■サンプルスクリプト

var arrange4 = $('#test4 li').clone();
$('button#btn4').one('click',function(){
	$('ul#test5').html(arrange4);
});

appendとかprependで表示させてもよかったのですが、今回はhtmlでcloneを入れた変数の中身を表示させてみます。

■サンプルデモ

  • テスト1
  • テスト2
  • テスト3
  • テスト4
  • テスト5
  • ここに複製されます

これでcloneの勉強にもなりました。

結局は覚えないと一般的ってことも一般的にならないなーと感じたりもしましたが、cloneというのがあるのですから、要素をコピーさせるときなどはcloneを使うと覚えておきます。

ご指摘してくださったお二方、ありがとうございました!

トップ画のソース

sad dog
Photographer
dharmabum60
License
Creative Commons (by)


この記事へのコメント
cloneを覚えるなら
var $clone = $(#foo).clone(true);
trueを渡すとイベントもコピーされるってとこまで覚えたらいかが?
Posted by y@s at 2009年05月10日
>y@sさん
コメントありがとうございます!
ご指摘の部分も勉強してみました。
イベントもコピーされるのは便利ですね。
教えていただき、ありがとうございます。
Posted by ハム at 2009年05月11日
コメントを書く
お名前: [必須入力]

メールアドレス: [必須入力]

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック

トップに戻る

×

この広告は180日以上新しい記事の投稿がないブログに表示されております。