[ プログラミング ] 複数トリガーで動作するアコーディオンメニューをjQueryで実装する方法

アコーディオンメニューについて色々と調べている最中に、以下の記事を発見しました。

メニューをクリックしたら、それに該当する項目まで内部リンクして、隠れていたコンテンツを表示したいというものです。勉強がてらに作ってみることにします。

デモは以下からどうぞ。

DOMO

HTML5でコーティングしています。jQueryもCSSもHTMLのheadタグ内に書いています。

HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="js/jquery.js"></script>
<script>
$(function(){
    // #で始まるアンカーをクリックした場合に処理
    $('.menu a[href^=#]').on('click', function() {
        // スムーススクロール
        var speed = 400;// ミリ秒
        var href= $(this).attr("href");
        var target = $(href == "#" || href == "" ? 'html' : href);
        var position = target.offset().top;
        $('body,html').animate({scrollTop:position}, speed, 'swing');

        // 開閉パネルが閉じていたら
        if($(href).children('.subInner').css('display') == 'none'){
            // 同時に開閉イベントを実行
            $(href).children('h4').trigger('click');
        }
        return false;
    });

    // 見出しをクリックするとコンテンツを開閉する
    $('.subContent h4').on('click', function() {
        $(this).next('div:not(:animated)').slideToggle();
        $(this).children('span').toggleClass('open');
    });
});
</script>
<style>
.wrap {
    width:800px;
    margin:0 auto;
}

.menu {
    margin:0;
    padding:0;
}

.menu li {
    float:left;
    margin-right:10px;
    list-style:none;
}

.menu li a {
    display:block;
    padding:10px 20px;
    color:#fff;
    background:#000;
    cursor:pointer;
}

.subInner {
    display:none;
    padding:10px;
    background:#f19c75;
}

.subContent h4 {
    margin:10px 0;
    padding:10px;
    line-height:20px;
    color:#fff;
    background:#000;
    cursor:pointer;
}

.subContent h4 span {
    display: block;
    background:url('images/arrow.png') 100% 0% no-repeat;
}

.subContent h4 span.open {
    background:url('images/arrow.png') 100% 100% no-repeat;
}
</style>
<title>HTML5サンプル</title>
</head>
<body>
<div class="wrap">
    <ul class="menu">
        <li><a href="#sub01">ボタン1</a></li>
        <li><a href="#sub02">ボタン2</a></li>
        <li><a href="#sub03">ボタン3</a></li>
        <li><a href="#sub04">ボタン4</a></li>
    </ul>

    <br>・・・

    <div id="sub01" class="subContent">
        <h4><span>項目1</span></h4>
        <div class="subInner">
            内容内容内容<br><br><br><br><br><br><br>
        </div><!-- /.subInner -->
    </div><!-- /.subContent -->

    <div id="sub02" class="subContent">
        <h4><span>項目2</span></h4>
        <div class="subInner">
            内容内容内容<br><br><br><br><br><br><br>
        </div><!-- /.subInner -->
    </div><!-- /.subContent -->

    <div id="sub03" class="subContent">
        <h4><span>項目3</span></h4>
        <div class="subInner">
            内容内容内容<br><br><br><br><br><br><br>
        </div><!-- /.subInner -->
    </div><!-- /.subContent -->

    <div id="sub04" class="subContent">
        <h4><span>項目4</span></h4>
        <div class="subInner">
            内容内容内容<br><br><br><br><br><br><br>
        </div><!-- /.subInner -->
    </div><!-- /.subContent -->

    <br>・・・

</div><!-- /.wrap -->
</body>
</html>

こういう何かをトリガーにしたい場合は、「.trigger()」を使います。メニューをクリックしたら、見出しをクリックした場合の動作も一緒にしたいので、20行目のように書きます。

また、コンテンツ部分がすでに開いているものに対しては、トリガーイベントを発動させないようにします。そうしないと、メニューをクリックしたらコンテンツ部分が閉じてしまうので。