QA@IT

javascript(jquery)について

3926 PV

javascript(jquery)について
初めまして。javascriptを頑張って勉強しています。
そこで下記コードがなぜ動かないのかどうしてもわからないので質問させていただきます。
下記HTMLコード

<ul id="hoge">
    <li>
        <select name="example">
            <option value="サンプル1">サンプル1</option>
            <option value="サンプル2">サンプル2</option>
            <option value="サンプル3">サンプル3</option>
        </select>
        <div class="col-lg-3 btn-area">
            <button id="btn" class="btn">追加</button>
        </div>
    </li>
</ul>

jqueryコード

    jQuery(document).ready(function () {
        var settings = $.extend({
            master: '#hoge'
        });
        var aaa = $(settings.master).clone(true); //li以下をクローン。このオブジェクト?を使い回したい。
        console.log(aaa);
        $('button').on('click',function(){
            $('#hoge').append(aaa);
        });
    });

上記コードだと一回目ボタンをクリックしたときにselectボックスとボタンが
追加されます。
しかし、2回目以降ボタンをクリックしても追加されません。

下記コードだとボタンを押した数だけli以下のコードが追加されます。

    jQuery(document).ready(function () {
        var settings = $.extend({
            master: '#hoge'
        });
        var aaa = $(settings.master).clone(true);
        console.log(aaa);
        $('button').on('click',function(){
            $('#hoge').append(aaa[0].outerHTML);
        });
    });

$('#hoge').append(aaa)と$('#hoge').append(aaa[0].outerHTML)違いはなんでしょうか?
なぜ$('#hoge').append(aaa)だと2回目以降追加されないのでしょうか?

jsを理解してないからだと思うのですが、どうかお分かりのかた教えて頂けると幸いです。
また、上記部分を理解する上で、「こういうところ勉強したほうがいいよ!」というアドバイスを頂けると幸いです。

回答

前者は、ボタンを押す度に毎回同じオブジェクトを追加しようとしているためです。

例えば、次のように同じオブジェクトを2回追加しているのと同じだからです。

    jQuery(document).ready(function () {
        var settings = $.extend({
            master: '#hoge'
        });
        var aaa = $(settings.master).clone(true);
        console.log(aaa);
        $('button').on('click',function(){
            $('#hoge').append(aaa);
            $('#hoge').append(aaa);
        });
    });

後者は outerHTML で一旦文字列にすることで append の中で DOM オブジェクトが再構築されているためです。つまり clone しているのと同じです。

例えば、次のようにしても動作します。

    jQuery(document).ready(function () {
        var settings = $.extend({
            master: '#hoge'
        });
        var aaa = $(settings.master).clone(true);
        console.log(aaa);
        $('button').on('click',function(){
            $('#hoge').append(aaa.clone());
        });
    });

なお、↑のコードだと ui 要素の id 属性まで複製されているので、要素を追加したときに id が重複してしまいます(もとの要素の id も hoge だし、追加した要素の id も hoge)。

なので、次のように id 属性を削除してやるか、

    jQuery(document).ready(function () {
        var settings = $.extend({
            master: '#hoge'
        });
        var aaa = $(settings.master).clone(true);
        aaa.removeAttr('id');
        console.log(aaa);
        $('button').on('click',function(){
            $('#hoge').append(aaa.clone());
        });
    });

あるいは、もう1段上の要素の id を指定して、

<div id="hoge">
    <ul>
        <li>
            <select name="example">
                <option value="サンプル1">サンプル1</option>
                <option value="サンプル2">サンプル2</option>
                <option value="サンプル3">サンプル3</option>
            </select>
            <div class="col-lg-3 btn-area">
                <button id="btn" class="btn">追加</button>
            </div>
        </li>
    </ul>
</div>

複製する要素に id 属性が含まれないようにする方が良いです。

    jQuery(document).ready(function () {
        var settings = $.extend({
            master: '#hoge > ui'
        });
        var aaa = $(settings.master).clone(true);
        console.log(aaa);
        $('button').on('click',function(){
            $('#hoge').append(aaa.clone());
        });
    });

あ、button 要素にも id 属性がありますね。これもどうにかする必要があります(不要なら id 属性を削除するとか class 属性で代替するとか)。

上記部分を理解する上で、「こういうところ勉強したほうがいいよ!」というアドバイス

素の JavaScript とか素の DOM とかでしょうかね? jQuery に隠蔽されていると jQuery しか判らなくなってしまうかもしれないので。

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。