今回は、Webサイトにおいて、必ずと言っていいほど使用されているJavaScript(jQuery)の機能と実装の際のテクニックをを紹介したいと思います。
※サンプルで実際に動作させているソースは、動作の比較をするために、説明で使用しているソースとは若干異なります。

アコーディオン

スマートフォンサイトでは良く見かけると思いますが、クリック(タップ)すると開閉するコンテンツです。
ナビゲーションやページが長くなりすぎたりするときによく使用されます。
今回はjQueryの「.slideToggle()」を利用したサンプルを紹介します。

HTML

  
開閉ボタン(クリックしてください)
  
    
  • 開閉コンテンツリスト
        開閉コンテンツリスト2   
  • JavaScript(jQuery)

    $(function(){
      $('.toggle dt').click(function(){
        $(this).next().slideToggle();
      });
    });
    

    アコーディオンサンプル1

    開閉ボタン(クリックしてください)
    開閉コンテンツ
    開閉コンテンツ

    「開閉ボタン」をクリック(タップ)すると、ボタンの下にある要素が600ミリ秒(0.6秒)で表示され、再度クリック(タップ)すると閉じます。
    上記のサンプルで正しく動いているようですが、「開閉ボタン」を連打してみてください。
    アニメーションのバッファが溜まってしまい、遅れてアニメーションが起きて、開いたり閉じたりを繰り返してしまいます。
    下は、それを解消したもので、アニメーションする要素(開閉するコンテンツ)が動作していないときだけ、開閉するようにしています。

    JavaScript(jQuery):改良版

    $(function(){
      $('.toggle dt').click(function(){
        if($(this).next().not(':animated').length >= 1){
          $(this).next().slideToggle();
        }
      });
    });
    

    アコーディオンサンプル2

    開閉ボタン(クリックしてください)
    開閉コンテンツ
    開閉コンテンツ

    スムーススクロール

    ページ内リンクを一瞬ではなく、ゆっくりと移動させる機能です。
    最近はほとんどのWebサイトで、「ページのトップへ戻る」にこの機能が実装されています。

    HTML

    ↑ページトップへ戻る

    JavaScript(jQuery)

    $('a[href^=#]').click(function(){
      var href= $(this).attr('href');
      var target = $(href == '#' || href == '' ? 'html' : href);
      var targetPos = target.offset().top; // 移動する位置
      var duration = 500; // 500ミリ秒
      
      $('html, body').animate({scrollTop:position}, duration, 'swing');
      return false;
    });
    

    スムーススクロールサンプル1

    ↑ページトップへ戻る

    ↓サンプル2へ

    上記のサンプルでも問題はありませんが、どんな移動量でも500ミリ秒(0.5秒)で移動することになってしまいます。
    ある移動量があるものなら気になりませんが、移動量がないものだと、とてもゆっくり動いているように見えてしまいます。
    下の改良版では、移動量を計算して、常に一定の速度で移動するようにしています。
    移動に1000ミリ秒(1秒)以上かかってしまうものは、1000ミリ秒(1秒)で移動するように最低速度を設けています。

    JavaScript(jQuery):改良版

    $('a[href^=#]').click(function(){
      var href= $(this).attr('href');
      var target = $(href == '#' || href == '' ? 'html' : href);
      var targetPos = target.offset().top;    // 移動する位置
      var scrollTop = $(window).scrollTop();  // 現在のスクロール位置
      var scroll = scrollTop - targetPos;     // 移動量
      
      // 移動量がマイナスの場合
      if(scroll < 0){ scroll = scroll * (-1);}
      var duration = 0.7 * scroll; // 1pxを0.7ミリ秒(0.0007秒)で移動した場合の時間
      
      // 時間が100ミリ秒以上は1000ミリ秒に設定
      if(duration > 1000){ duration = 1000;}
      
      $('html, body').animate({scrollTop:targetPos}, duration, 'swing');
      return false;
    });
    

    スムーススクロールサンプル2

    ↑ページトップへ戻る

    ↑サンプル1へ

    この改良した機能は、アコーディオンの展開速度にも応用できます。(展開する高さによって速度を調整)

    とても細かいことではありますが、JavaScriptをただ実装するだけでなく、こういったひと手間・ひと工夫を加えることで、Webサイトはよりよいものになっていきます。
    今後も何が一番良いかを常に考え、最善の提案をさせていただければと思っています。

    Shinya Yoshida

    Writer
    Shinya Yoshida
    Category
    Works
    Tag
    Javascript,jQuery,アコーディオン,スムーススクロール