jquery スムーズスクロールでタブ切り替えが効かなくなった

Bootstrap, テクニック, ,
Pocket

jQueryを利用してスムーズスクロールを導入した際、タブナビゲーションを利用しているページでタブ切り替えが出来なくなりました。

今回はその解決方法をご紹介します。

導入しているスムーズスクロール

$(document).ready(function () {
//スムーズスクロール
$('a[href^=#]').click(function () {
 var speed = 500;
 var href = $(this).attr("href");
 var target = $(href == "#" || href == "" ? 'html' : href);
 var position = target.offset().top;
  $("html, body").animate({
   scrollTop: position
  }, speed, "swing");
 return false;
 });
});

jQueryのプラグインではなく、簡単な記述で実装できるこちらを導入しました。いろいろな方が紹介されている有名なスクリプトです。

タブ切り替えができなくなった原因は、このスクリプトがタブナビゲーション部分とバッティングしてしまったものでした。

指定した要素を除外する :not(selector) を使う

スムーズスクロールさせるスクリプトの最初の部分$('a[href^=#]')、この指定方法だとタブナビゲーションのアンカーリンクも含まれてしまうのが動かなくなる原因でした。

$('a[href^=#]').click(function () .... 

そこで :not(selector)をつかってスムーズスクロールさせる必要がないアンカーリンクを除外します。
今回はタブナビゲーションで利用しているidがそれに該当します。

例えば、2つのタブがあり <a href="#tab01">・・・</a><a href="#tab02">・・・</a>となってる場合、
$('a[href^=#]')には次のような除外する記述を追加します。

$('a[href^=#]' + 'a:not([href *= "tab01"])' + 'a:not([href*="tab02"])').click(function () ....

これでアンカーリンク#tab01#tab02が除外され、タブナビゲーションは切り替えができるようになりました。

それ以外ではスムーズスクロールも有効のままになりました。

汎用性のある :not(selector) 指定例

上の例のままでは指定が直接すぎて汎用性に欠けます。
そこでスムーズスクロールから除外したい<aタグ>に共通のclass(例えば .non-scroll)など指定しておく方法がいいでしょう。

$('a[href^=#]' + 'a:not(.non-scroll)').click(function () 

Bootstrap3での :not(selector) の使用例

Bootstrap3 のタブナビゲーションなら、data-toggle="tab" や data-toggle="pill" をつかうので

$('a[href^=#]' + 'a:not([data-toggle="tab"])').click(function ()  ....
$('a[href^=#]' + 'a:not([data-toggle="pill"])').click(function () .... 

と指定してくのがいいでしょう。

:not(slecter) に指定できるslecter の種類や例は jQuery リファレンス:セレクタ目次 が参考になります。