LoginSignup
2
1

More than 3 years have passed since last update.

jQueryのappendで取得元が消えてしまうときの回避方法

Last updated at Posted at 2020-04-04

はじめに

エレメントから要素を取得して、その要素を別の場所にコピーする処理をjQueryのappendでしようとしていたのですが、取得元が消えてしまいハマってしまったので、その回避策のメモです。

事象

以下のような画面があったとして、「テストタイトル1」をクリックすると、「テストタイトル2」の下に「テスト内容」がコピーされるプログラムを作成したかったとします。

テストタイトル1 // ① クリック
テスト内容
テストタイトル2 // ② この下に「テスト内容」がコピーされる

そこで、以下のようなHTMLとJavascriptを実装します。

<html>
  <head>
    <meta charset="utf-8">
    <title>テスト</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  </head>
  <body>
  <div id="test" class="test">
    <div class="test-title-1">
      テストタイトル1
      <div class="test-contents">テスト内容</div>
    </div>
    <div class="test-title-2">
      テストタイトル2
    </div>
  </div>
  </body>
  <script>
    $('.test-title-1').on('click', function(){
      const target = event.currentTarget; // クリックした要素(test-title-1)を取得
      const testContents = $(target).find('.test-contents'); // test-contentsクラスの要素取得
      $('.test-title-2').append(testContents); // test-title-2クラスへappend
    });
  </script>
</html>

すると、なぜか結果は以下のようになり、「テストタイトル1」直下のテスト内容が消えてしまいます。

テストタイトル1
テストタイトル2
テスト内容

原因

jQueryオブジェクトのappend()は追加or移動という仕様でした。

公式サイトを見ると、以下のように記載がありました。

If an element selected this way is inserted into a single location elsewhere in the DOM, it will be moved into the target (not cloned)
(日本語訳)
「この方法で選択された要素がDOMの他の場所の単一の場所に挿入された場合、それはターゲットに移動されます」

つまり、取得したDOMはappendすると、別の要素へ移動されてしまうのです。。。

回避策

これを回避するには、appendする時に、変数を複製すればOKです。

先ほどのサンプルプログラムを利用すると、具体的には、clone()メソッドを以下のように使います。

<html>
  <head>
    <meta charset="utf-8">
    <title>テスト</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  </head>
  <body>
  <div id="test" class="test">
    <div class="test-title-1">
      テストタイトル1
      <div class="test-contents">テスト内容</div>
    </div>
    <div class="test-title-2">
      テストタイトル2
    </div>
  </div>
  </body>
  <script>
    $('.test-title-1').on('click', function(){
      const target = event.currentTarget;
      const testContents = $(target).find('.test-contents').clone(); // ここにclone()を追加
      $('.test-title-2').append(testContents);
    });
  </script>
</html>

すると、取得した要素は一度クローン(複製)されるため、appendが移動するのは複製した要素となるので、以下のように正常にコピーできます。

テストタイトル1 // ① クリック
テスト内容
テストタイトル2
テスト内容 // ② テスト内容が正常にコピーされる

さいごに

2020年から個人ブログはじめました!

フリーランスエンジニアになって得た知識と経験をもとに、フリーランスエンジニアに関する情報をはじめ、IT技術情報や業界情報、エンジニアライフハック等のコンテンツを配信していく予定です。

まだまだ記事数は少ないのですが、週単位で更新してますので、もしご興味ございましたら、みていただけると嬉しいです。

さいごまでお読みいただき、ありがとうございました。

2
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1