質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.34%

hiraku.jsで作成したスマホメニューのリンクで、リンク押下時ページ内スクロールが正常に動作しない

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 2,404

score 14

前提・実現したいこと

ドロワーの作成にjsプラグイン「hiraku.js」を使用しているのですが、スマホメニューのリンクの挙動がおかしく、困っています。
hiraku.jsを使用したことがある方、似たような事例で詰まった経験のある方いましたら、
正しくナビゲーションを設置する方法をご教授いただけましたら幸いです。
なお、ナビゲーションはページ内遷移(リンク位置にスクロール)となります。

詳しくは現在作成中のサイトをアップしましたので、スマホ画面のナビゲーションの挙動をご確認ください。
https://satori-log.com/product/30daystrial-final/

発生している問題・エラーメッセージ

1. メニューのリンクを押しても画面がその位置までスクロールしない

原因:
メニューを開いたときにhiraku.jsが画面を固定しているため

自分なりの解決策:
jQueryでbodyに対して、positionとoverflow設定を初期値に指定し直すことでスクロール固定を解除

2. スクロール固定解除後、メニューのリンクを押し、メニューを閉じたとき、画面のスクロール位置が画面最上部に戻ってしまう

原因:不明

推測:hiraku.jsの何らかの設定によるもの

自分なりの解決策の推測:hiraku.jsの初期設定をjQuery等で上書きする

補足:

  1. 「メニューのリンクを押しても画面がその位置までスクロールしない」がそもそもの問題でして、
    それを解決後に、
  2. 「スクロール固定解除後、リンクを押し、メニューを閉じたとき、画面のスクロール位置が、画面最上部に戻ってしまう」が起きている状況です。
    1の解決方法が正しかったのか、
    また、それが正しかった場合、2はどのようにして解決すれば良いのか知っている方は教えてくださると幸いです。

エラーメッセージはありません。

該当のソースコード

該当箇所を抜粋しました。

スマホメニューに関するHTML

<body class="drawer drawer--right">
    <header role="banner">
        <!-- ハンバーガーボタン -->
        <button type="button" class="hiraku-open-btn" id="offcanvas-btn-right" data-toggle-offcanvas="#js-hiraku-offcanvas-1" aria-expanded="false">
            <!-- <span class="hiraku-open-btn-line"></span> -->
            <img class="open-btn" src="img/hamburger.svg" alt="ハンバーガーボタン">
            <img class="close-btn" src="img/batsu.svg" alt="閉じるボタン">
        </button>
        <!-- モバイルメニュー -->
        <nav class="mobile-nav offcanvas-right" role="navigation">
            <ul class="navbar-nav">
                <li class="nav-item">
                    <a href="#news" class="nav-link">News</a>
                </li>
                <li class="nav-item">
                    <a href="#service" class="nav-link">Service</a>
                </li>
                <li class="nav-item">
                    <a  href="#results" class="nav-link">Results</a>
                </li>
                <li class="nav-item">
                    <a href="#qa" class="nav-link">FAQs</a>
                </li>
                <li class="nav-item">
                    <a href="#price" class="nav-link">Price</a>
                </li>
                <li class="nav-item">
                    <a href="#comments" class="nav-link">Comments</a>
                </li>
                <li class="nav-item">
                    <a href="#contact" class="nav-link">Contact</a>
                </li>
            </ul>
        </nav>
    </header>
</body>

スマホメニューの動作関連

$(document).ready(function () {
  // スマホメニューの開閉
  $(".offcanvas-right").hiraku({
    btn:"#offcanvas-btn-right",
    direction:"right"
  });

  // リンクを押したとき画面のロックを解除する
  $('a[href^="#"]').click(function() {
    $('body').css('position', 'static');
    $('body').css('overflow', 'scroll');
    $('body').css('overflow-y', 'scroll');
  });
});

リンク押下時のスクロール動作関連

$(document).ready(function () {
  $('a[href^="#"]').click(function() {
      var speed = 400;
      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;
  });
});

試したこと

一通り調べてみたところ、似た事例が存在しました。
ただ、解決策に「PCを再起動」とありましたが、私の場合、やってみても変わりませんでした。
一応載せておきます。
https://teratail.com/questions/200664

補足情報(FW/ツールのバージョンなど)

実行環境

・Mac
・Chrome

プラグイン

・jQuery.3.4.1
・hiraku.js

画面サイズ

モバイル(767px以下)

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

+2

自己解決しました。

結論から言うと、
hiraku.jsの機能で画面が固定されていたので、メニューのリンクを押下した際に、画面固定を解除してあげればOKです。

修正の際は、jQueryで下記を記述しました。

hiraku.jsでページ内リンクを機能させる方法

$(document).ready(function () {

 // スマホメニューの開閉
  $(".offcanvas-right").hiraku({
    btn:"#offcanvas-btn-right",
    direction:"right"
  });

  // スマホメニューを開くとき
  $('.hiraku-open-btn').click(function() {

    // ヘッダーの表示を切り替える
    $('header').css('background-color', 'rgba(62, 62, 62, 0.7)');
    $('.hiraku-open-btn').css('margin-left', '81.39px');
    $('.open-btn').hide();
    $('.close-btn').show();
  });

  // スマホメニューを閉じるとき
  $(document).click(function(event) {
    if(!$(event.target).closest('.offcanvas-right').length 
    && !$(event.target).closest('.hiraku-open-btn').length) {

      // ヘッダーの表示を切り替える
      $('header').removeAttr('style');
      $('.hiraku-open-btn').removeAttr('style');
      $('.open-btn').show();
      $('.close-btn').hide();
    }
  });

  // リンクを押したとき
  $('a[href^="#"]').click(function() {

    // 画面のロックを解除する
    $('body').css('position', 'static');
    $('body').css('overflow', 'scroll');
    $('body').css('overflow-y', 'scroll');

    // メニューを閉じる
    $('.js-hiraku-offcanvas-open').hide();
    $('.js-hiraku-offcanvas-body-right').removeAttr('style');

    // ヘッダーの表示を切り替える
    $('header').removeAttr('style');
    $('.hiraku-open-btn').removeAttr('style');
    $('.open-btn').show();
    $('.close-btn').hide();

    // classを初期化する
    $('body').removeClass('js-hiraku-offcanvas-body-right');
    $('.hiraku-open-btn').removeClass('js-hiraku-offcanvas-btn-active');
    $('.hiraku-open-btn').attr({'aria-expanded' : 'false'});
    $('.js-hiraku-offcanvas').removeClass('js-hiraku-offcanvas-open');
    $('.js-hiraku-offcanvas-sidebar').removeClass('active');

    // styleを初期化
    $('html').removeAttr('style');
    $('body').removeAttr('style');
    $('header').removeAttr('style');
    $('.hiraku-open-btn').removeAttr('style');
    $('.close-btn').removeAttr('style');
    $('.js-hiraku-offcanvas').removeAttr('style');
  });

});

ソースの説明

基本的な流れは次の通りです。

スマホメニューを開くとき

ボタンをクリックすると実行されます。
ボタン画像の切り替えや位置調整などを行います。
この部分はリンクを機能させるのとあまり関係ないです。
任意で記述してください。

スマホメニューを閉じるとき

スマホメニューとボタン以外の背景をクリックしたときに実行されます。
この時点で、スマホメニューを開いたときに設定したstyle設定を削除します。

リンクを押したとき

ここが肝です。
スマホメニューのリンクをクリックしたときに実行されます。

まず、画面のロックを解除し、スクロールできるようにします。

ただし、リンクを押したときにメニューが開いたままだと、メニューを閉じた瞬間に画面スクロールが画面最上部に戻ってしまいます。
そのため、リンクを押した瞬間にメニューを閉じるという処理も追加してあげる必要があります。

次に、ボタン画像の切り替えや位置調整など、ヘッダーの表示にまつわる記述をします。
これは任意でおこなってください。

最後に、classとstyle指定を初期化し、ボタンを開く前の状態に戻します。
hiraku.jsの機能で閉じているわけではないので、ボタンを開いたときに付加されたclassはメニューを閉じても残り続けます。そのため、リンクを押した段階で明示的に削除してあげる必要があるのです。

まとめ

説明は以上になります。

こういったJSのプラグインなどで詰まったら、基本的にはプラグインのソースをみて、対処するのが一番かもしれません。
しかし、ソースを見てもよく分からないという場合もあると思います。
その場合には、Chromeの検証ツールなどで、ボタンを押す前、押した後などを比較し、
classやstyleやプロパティの値がどう変化しているのかを見て対処していくのが良いかと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る