スキップしてメイン コンテンツに移動

Bootstrap3のAffixバグについて

【Affixとは】




サイドメニューなどを、画面と一緒にスクロールさせずに固定位置で表示するためのBootstrapのビルトイン便利JSです。
http://getbootstrap.com/javascript/#affix

また、サイドメニューの上部高さとフッターの高さを指定すると、上部高さまで、および、フッターが表示されるとフッターに押されて画面と一緒にスクロールされます。

上部高さはoffsetオプションのtopで指定し、フッターの高さはoffsetオプションのbottomで指定します。
具体例は以下

$('サイドメニュー').affix({

  offset: {

    top: function () {

      return (this.top = $('ヘッダー部分').outerHeight(true))

    },

    bottom: function () {

      return (this.bottom = $('フッター部分').outerHeight(true))

    }

  }

});


【バグの事象】(v3.1.1で確認)

スクロール中は動的にJSにより.affixクラスが付与され、position:fixed(自分でCSSに設定)となりサイドメニューの位置は固定され、bottom(フッター位置)までスクロールすると、動的にJSにより.affix-bottomクラスが付与され、position:absolude(自分でCSSに設定。top位置はJSが計算)となり画面と一緒に上に移動してゆきますが、スクロールで上部に切り返しても.affix-bottomが解除されず位置がフッターの上部に固定されたままになってしまいます。
(一旦、画面上部までスクロールすると.affix-topが付与され、サイドメニューは初期位置までジャンプします。その後画面下部にスクロールすると.affixが付与され正常動作(位置固定)しますが、bottomまでスクロールされると上記不具合(.affix-bottomクラスが付与され解除されない)が発生します。)


【バグの報告】

以下でバグ報告が挙げられています。
https://github.com/twbs/bootstrap/issues/9342
https://github.com/twbs/bootstrap/issues/12736


【修正されたaffix.js】

以下からダウンロード可能です。(2014.3.26現在)
https://github.com/twbs/bootstrap/blob/master/js/affix.js


【主な修正点】

<NG>
    if (affix == 'bottom') {

      this.$element.offset({ top: scrollHeight - offsetBottom - this.$element.height() })

    }

<OK>
    if (affix == 'bottom') {

      this.$element.offset({ top: position.top })

    }

NGは、スクロール高さ(=サイト全体の高さ)からオプションで指定したbottomの高さとサイドメニュー自身の高さを引いた位置をtopの位置としていましたが、サイドメニューの高さや、フッターの高さに影響され不具合が発生する場合があります。
OKは、単純に自身の位置をサイドメニューのtopの位置に変更されています。

以上です。


Bootstrapはとても便利で今やRWDのサイト制作には欠かせないフレームワークですが、Bootstrap自体にバグがあるとにっちもさっちもゆかなくなります。(自分のコードに問題がなくても事象が解決されないので何時間も悩んでしまいます。)

それでもいちからRWDを自前で制作しようとすると
・幅pxを%に計算すると...
・このJS使いたいけどレスポンシブ対応してるかしら...
・こんな共通クラスあったら便利だからまず作っておいて...
・わー、このサイトもう自分しか解読できないな...
みたいなことで悩む時間をBootstrapが解決してくれますから断然Bootstrapの使用をオススメします。

コメント

このブログの人気の投稿

iframeに異なるドメイン(クロスドメイン)のコンテンツを読み込んで高さを自動調節する方法

趣旨 iframe(親)に異なるドメインのページ(子)を読み込んで、親フレームにスクロールが出ないよう、iframeの高さを子ページの高さに自動調節する


方法 普通にやると、
「Uncaught SecurityError: Blocked a frame with origin "http://hoge.com" from accessing a frame with origin "http://fuga.com".  Protocols, domains, and ports must match. 」
などと怒られてしまいますのでこちらを参考に
http://stackoverflow.com/questions/18456498/how-can-i-change-the-size-of-an-iframe-from-inside

http://i556tips.tumblr.com/post/15710917018/%E3%82%AF%E3%83%AD%E3%82%B9%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%81%A7iframe%E3%81%AE%E9%AB%98%E3%81%95%E3%82%92%E8%87%AA%E5%8B%95%E8%AA%BF%E7%AF%80%E3%81%99%E3%82%8Bjavascript


コード hoge.com(親)
<html> <head>     <title>親</title>     <script src="js/jquery.js"></script>     <script>         window.addEventListener('message', function(e) {         var iframe = $("#fugapage");         var eventName = e.data[0];         var data = e.data[1];         switch(eventName) {             case '…

Googleタグマネージャー|iFrameの中で入力・確認・完了画面が遷移する場合の仮想ページビューのトラッキングの仕方

【概要】 Googleタグマネージャーをページに仕込んでおくと、仕込んだページ側のコードを一切変更することなく、後から動的にページビューやらイベントやらをタグマネージャー側の管理画面で動的にトラッキングすることができてとても便利なわけですが、ページがiframeの中で入力->確認->完了画面と遷移する場合、iframeの側(読み込む側)にタグマネージャーのタグを仕込んでおいても、目的のページビューがトラッキングできません。
そこでiframeで読み込まれた側の任意のページビューをトラッキングするためにGoogleタグマネージャーのdataLayerを利用する方法を記載します。
更に今回は、別々のiframeから共通で読み込まれたページでも外側のiframeに隠しコードを仕込み、どのiframeで読み込まれたのか判定して任意のトラッキング(仮想ページビュー)を行う方法をご紹介(提案)します。


【やりたいことをもう少し具体的に】 ページ要素として ・親フレームA ・親フレームB ・投稿フォーム とあった場合で
・親フレームA <= 投稿フォーム ・親フレームB <= 投稿フォーム と読み込んでいる場合に
Googleタグマネージャーを使用して、親フレームAでの入力画面、親フレームBでの確認画面、、、等の仮想ページビューをトラッキングしたい。

【HTML】(親フレームA) 親フレームAに以下のタグを記述(非表示の判定フラグ用) <div id="post_which" style="display:none;">frameA</div> ※親フレームAにはGoogleタグマネージャーのタグは仕込みません。

【HTML】(親フレームB) 親フレームBに以下のタグを記述(非表示の判定フラグ用) <div id="post_which" style="display:none;">frameB</div> ※親フレームBにもGoogleタグマネージャーのタグは仕込みません。

【投稿フォーム・入力画面】 読み込まれる投稿フォームの入力画面に以下のコードを記述

<body>の直下に Googleタグマネージャーのコードを設…

WordPressのwp_get_archivesで月別リストを生成する際に<li>をカスタムする方法

【About】 WordPressの wp_get_archives('type=monthly') で月別のリスト<li>を生成する際に、特定の年月のアーカイブページを表示した際に<li>に特定のクラス(class="active"など)を設定する方法を記載します。
また、おまけとして、functions.phpによらず、テンプレートで<li>をカスタマイズする方法も記載します。

【通常の書き方】 <WordPress>ーテンプレート
<p>月別アーカイブ</p> <ul>     <?php wp_get_archives('type=monthly')); ?> </ul>
とすると

<HTML><p>月別アーカイブ</p> <ul>     <li><a href="http://hoge.com/2013/12/">2013年12月</a></li>     <li><a href="http://hoge.com/2013/11/">2013年11月</a></li> </ul>
などと生成されます。

これを、ある月を表示しているときに、該当のリスト<li>に class="active" を追加したいとします。

【カスタマイズ方法】 <WordPress>ーテンプレート
<p>月別アーカイブ</p> <ul>     <?php wp_get_archives('type=monthly')); ?> </ul> (変更なし)

ーfunctions.php
functions.phpに以下を追加
<?php ・・・ function my_archives_link($link_html){   $my_month = '/' . get_query_var('year') . &#…