125naroom / デザインするところ(会社)です。

【jQuery】アコーディオン、エリア外からのアンカーでアコーディオンが開く、そしてアンカー場所へ移動する。

【jQuery】アコーディオン、エリア外からのアンカーでアコーディオンが開く、そしてアンカー場所へ移動する。
きのこさん
あのー、アンカーリンクのボタンを押したらアコーディオンが開いてその中にあるアンカーリンクの場所にスルスルーと移動させたいのですが可能ですかね?
きのこさん
なんだかややこしそうですが、やってみましょうかー

さっそく実装してみる

See the Pen
【jQuery】アコーディオン、エリア外からのアンカーでアコーディオンが開く、そしてアンカー場所へ移動する。
by 125naroom (@125naroom)
on CodePen.

コードはこちら

HTML

<section class="section">
  <div class="anchor">
    <ul>
      <li>
        <a href="#anchor1">アンカー1へ</a>
      </li>
      <li>
        <a href="#anchor2">アンカー2へ</a>
      </li>
      <li>
        <a href="#anchor3">アンカー3へ</a>
      </li>
    </ul>
  </div>
  <div class="more">もっとみる(アコーディオン)</div>

  <div class="one-detail hide">
    <div class="one-body" id="anchor1">
        <p>アンカー1</p>
    </div>
    <div class="one-body" id="anchor2">
        <p>アンカー2</p>
    </div>
    <div class="one-body" id="anchor3">
        <p>アンカー3</p>
    </div>
  </div>
</section>

CSS

うーん、絶対に必要なものだけ記載しておきます。デザインはおまかせしますー。

.hide {
  display: none;
}

jQuery

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

一行解説したいところですが、ざっくり説明すると、
スルスルーとスクロール設定、待機設定、アコーディオン設定、アンカーからのアコーディオン設定、をしています。

$(function(){
  //scrollTo
  function scrollTo(_target, _offset){
    var
      _f = true,
      _s = 500,
      _t = 0;

    if(_target && _target.length){
      try{
        _t = _target.offset().top;
      }
      catch(e){
        _f = false;
      }
    }
    if(_offset !== undefined){
      _t = Math.max(0, _t + _offset);
    }
    if(_f){
      $('body, html').animate({scrollTop: _t}, _s, 'swing');
    }
  }
  //wait
  $.wait = function(msec) {
    var d = new $.Deferred;

    setTimeout(function(){
      d.resolve(msec);
    }, msec);

    return d.promise();
  };
  //more
  $('.section').find('.more').click(function(){
    var _p = $(this).closest('.section');
    _p
      .toggleClass('is-open')
      .find('.one-detail').slideToggle(250);

    if(_p.hasClass('is-open')){
      $.when(function(){
        return $.wait(100);
      }())
        .then(function(){
        scrollTo(_p.find('.one-detail'), -48.8);
      });
    }
    return false;
  });
  //anchor + open
  $('.section').find('.anchor').find('a').unbind().click(function(){
    var
      _p      = $(this).closest('.section'),
      _target = $($(this).attr('href')),
      _wait   = 300;

    if(_p.hasClass('is-open')){
      _wait = 100;
    }

    _p
      .addClass('is-open')
      .find('.one-detail').show();

    $.when(function(){
      return $.wait(_wait);
    }())
      .then(function(){
      scrollTo(_target, -0);
    });
    return false;
  });
});

サンプルページはこちら

メモ

jQueryのことで何かわからないことがあればjQueryの日本語リファレンスサイトがあるので一度チェックしてみるのをおすすめします。

jQuery日本語リファレンス

jQuery(英語版)

さいごに

きのこさん
おー、これこれー!
きのこさん
なかなかややこしかったですねー。さ、甘いもの食べに行きましょうー

関連記事

【jQuery】アコーディオン実装サンプル10選

【jQuery】アコーディオンでおしゃれなQ&Aを作ってみる

【jQuery】ページ内リンクでスムーズスクロール(スクロール位置の調整も簡単にできる)

おすすめ

Googleさんのおすすめ

Googleさんのおすすめ

デザインの記事

NEWTOWN/グラフィック・Webデザイン
ちょっと思い出しただけ
【CSS】見出しデザインをまとめてみる(左右に線を引くとか)