[js]<dl>で作ったアコーディオンと初期設定について

検証見つつやると分かるネタ。

こう

<dl>
    <dt>title</dt>
    <dd>detail</dd>
    <dt>title</dt>
    <dd>detail</dd>
    <dt>title</dt>
    <dd>detail</dd>
    <dt>title</dt>
    <dd>detail</dd>
    ⋮
</dl>
dl{
    margin: 0;
    padding: 0;
    display:flex;
    flex-direction: column;
    dt,dd{
        margin: 0;
    }
    dt{
        &.active{
            //表示時
        }
    }
    dd{
        display:none;
    }
}
$(function(){
    $('dl dt').on('click',function(){
        $(this).toggleClass('active');
        $(this).next('dd').slideToggle();
    })
})

これで作ると、初期設定時は全部格納された状態になる。

初期状態で表示させたい時

HTML側で書くのが一つ。

<dl>
    <dt class="active">title</dt>
    <dd style="display: block;">detail</dd>
    ⋮
</dl>

styleの直書きが嫌だったら、HTML+jQueryでこうする。

<dl>
    <dt class="active">title</dt>
    <dd>detail</dd>
    ⋮
</dl>
$(function(){
    $('dl dt.active').next('dd').css('display','block');
    $('dl dt').on('click',function(){
        $(this).toggleClass('active');
        $(this).next('dd').slideToggle();
    })
})

jsでstyleを当てるとページの高さが変わるんで、そういうのが気持ち悪い人は全部html側で書いちゃえよという2択ですね。

だめな書き方

これが今回のネック。

$(function(){
    $('dl dt.active').next('dd').slideDown();
})

.slideDown()でも.show()でも同じなんだけど、読み込み時の表示設定は、ブラウザ上では普通に機能してるんだけど、そこから.slideToggle()を発火させるとdisplay:block;が付与される。
つまり、.toggleClass()は.removeClass()の動作になるんだけど、.slideToggle()は.slideDown()の動作になる。

だからダメです。

バグじゃないかなこれ。

コメント

タイトルとURLをコピーしました