ページ内リンクで、スムーススクロールを設定する方法等について

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 1,463

yafoo

score 14

全くの初心者ですが、以下内容について質問させて頂ければと思います。

 現時点取り組んでいること

サンプルHPのように、日本地図をクリック(もしくはタップ)すると、ページ内の該当場所に移動するページを作成しております。
日本地図は、このプラグインを使用し作成しております。

 発生した問題

ページ内リンク自体は、うまくいきました。
クリックすると、指定した箇所に無事飛びます。

ただし、これはスマホに顕著なのですが、タップして移動した先にリンクがあると、そのままそのリンクを開いてしまうという不具合が発生します。
(意味分かるでしょうか・・・)

解決策として、大きく以下2つを考えております。

 解決案1 スムーススクロールを設定する

第一候補として、スムーススクロールの実装を考えております。
(個人的には、できるだけこの動きを実装させたいと考えております。スクロールしたことが分かりやすいですし)

ネット検索して以下コードを記載してみたものの、私のHPではaタグではなくプラグインを使用しているため(案の定)上手くいきませんでした。

$(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;
  });
}); 

その次に

html{scroll-behavior: smooth}


と記述したところ、Chromeでは上手く動作しましたがその他ブラウザ(iPhone safari等)では変化なしでした。
(ブラウザがサポートしていないからでしょうね)

 解決案2 スクロール後の動作を追加する

移動後すぐにリンクが開かないよう、スクロール後にフェードイン等の動作をつけることも解決策かと思います。

一通り検索して調べてみましたが、フェードインの場合CSSのopacityを利用して動作させるようなので、リンクは開けてしまうのではないかと思います。

まだ実装していないので憶測で上記書いておりますが、この観点でもアドバイス等ございましたら、ご教示頂けないでしょうか。

 最後に

解決案1・解決案2どちらでも構いませんので、対処法をご教示頂けますとありがたく存じます。
(それ以外の解決策もございましたら、是非教えて頂けるとありがたいです)

何卒、宜しくお願い致します。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

+1

根本原因についての憶測なのですが、SPで固有で発生する「300ms delay問題」かもしれないなと推測しました。
clickが遅れて発動するので、スクロール後に同位置にタップイベントが走ってしまうという。

これが原因であれば、click時のスクロールをtimeoutなどで300ms遅らせればクリアするのではないかと思います。
(スムーススクロールができないのはそれはそれで気になるのですが...。)

もしくは、この300ms delay自体を無くしてしまっても良いかもしれません。
こちらのサイトが参考になります。
副作用がありますので、注意してください。なぜ300ms遅らせているのか?についても記載があります。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/04/06 19:26

    すみません、スムーススクロールの実装に夢中になっていたのですが、この回答も大変参考になりました。
    (根本として、そのような問題があることすら知りませんでした)

    今後何かの際に活用させて頂くかもしれません。
    何卒、宜しくお願い致します。

    キャンセル

+1

そもそもサンプルページで

  • jqueryを2度読み込んでいる
  • 404の外部ファイルが複数ある
  • scriptの閉じタグに誤りがある

など色々と修正して欲しい箇所はありますが、
要はpathをクリックした際の挙動を捉えて
アンカーリンクまで飛ばせば良いので、
スムーススクロール自体の処理としては

$('path').click(function(){
    var speed = 500;
    var target= $(this).attr("id");
    var target= target.replace("map_", 'sec');    
    var position = $('div[id="' + target + '"]').offset().top;
    $("html, body").animate({scrollTop:position}, speed, "swing");
    return false;
});


で良いかと思います。

スクリプトの記述の誤りについては
閉じタグの対応具合をよく見て対処してみてください。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/04/05 14:26

    すみません、早速htmlにscriptタグで入れ込んでみたのですが残念ながら挙動に変化がありません・・・。
    もしかしたらご指摘の通りjQueryの挙動自体に問題があるかもしれませんが、なにぶん初学者なもので、原因等分かりましたらご教示頂けないでしょうか。
    申し訳ございませんが、何卒宜しくお願い致します。

    キャンセル

  • 2018/04/05 14:48

    まずchromeデベロッパーツールで
    consoleにどのようなエラーが出ているかを記載してください。
    "console"タブを開いて赤く目立っていればまずそこがエラーです。
    https://developers.google.com/web/tools/chrome-devtools/console/?hl=ja

    サンプルページを編集できるようであればそうしてください。
    実際の編集してみたコードを見てみないと
    アドバイスするにも限界があります。

    キャンセル

  • 2018/04/05 15:29

    確かに仰る通りです、大変失礼いたしました。
    取り急ぎ、Consoleで指摘された内容に基づきサンプルページを修正致しました。

    提示頂いたコードにつきましては、headタグ内に記載しております。
    何卒、宜しくお願い致します。

    キャンセル

checkベストアンサー

0

コメントを受けて回答いたします。

まずjQueryのお約束事を覚えておくと良いと思います。

基本的に$(function(){...});とは
jQuery(document).ready(function(){...});の略のことなので
documentを全て読み込んだ後にjQeryを実行してください、という意味です。
ですので書き方としては、

$(function(){
    $('path').click(function(){
        var speed = 500;
        var target= $(this).attr("id");
        var target= target.replace("map_", 'sec');    
        var position = $('div[id="' + target + '"]').offset().top;
        $("html, body").animate({scrollTop:position}, speed, "swing");
        return false;
    });    
});


として、jQueryを使用しているということを明示して
documentを読み込んだ後に実行しておく必要があります。

また、上記の実行タイミングのこともあるので
jQueryなどのscriptは書いてある順に上から実行されるので
head内ではなくbodyの閉じタグ直後に書いておくと何かと便利です。
(headに書くと描画速度を低下させる恐れがあります。)

ご確認ください、

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/04/05 17:24

    大変初歩的な点からご教示頂いたと思っております。
    誠にありがとうございます。

    頂いたコードを基に再度サンプルHPを修正しましたが、クリック後本来意図していた箇所とは違う場所に移動する等の不具合が生じてしまいます。
    挙動的にも、一度下に行ってから上に戻る・・・等の動作が散見されます。
    ここまでくると恐らくプラグインとの整合も原因ではないか・・・と思い、プラグイン側も色々といじっている最中ですが、もし修正案等ございましたら、ご連絡頂けないでしょうか。

    本当に、度々申し訳ございません。

    キャンセル

  • 2018/04/05 18:32

    プラグインとクリックイベントが競合しています。
    map-interact.jsの57行目〜と79行目〜あたり、

    if(map_config[id]['target'] == 'new_window'){
    window.open(map_config[id]['url']);
    }else if(map_config[id]['target'] == 'same_window'){
    window.location.href=map_config[id]['url'];
    }

    のことです。

    id要素のtarget属性を読み取って処理を変えているようです。
    別ページで開いたりスクロールをさせずにアンカーリンクさせたい場合は必要ですが、
    今回の要望の限りでは必ずも必要ではありません。

    また、今回書いたscriptはあくまで#map_数字をdiv[id="数字"]に変換するものです。
    クリックする要素のidとアンカーリンク先の数字を合わせて下さい。

    キャンセル

  • 2018/04/06 19:24

    色々と聞いてしまったにも関らず丁寧にご対応頂きまして、
    大変ありがとうございました。(サーバーには上げずローカルで確認したのみですが)おかげ様で無事実装できました。
    これを機にもう少しJS系勉強することにします・・・

    今後とも、何卒宜しくお願い致します。

    キャンセル

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

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