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

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

ただいまの
回答率

89.21%

アンダーバーが追いかけてくるメニューについて

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,878

yuika39

score 16

web初心者です。分かりにくい部分多々あると思いますがよろしくお願いいたします。

ただいま1のCSSのみで実装できるメニューを実装していたのですが、こちらのメニューを2のようにクリックしたところ、最後にマウスオーバーしたところにアンダーバーをとどめておくような設定は可能でしょうか?

また普通にマウスホイールでスクロールした場合それに合わせメニューのアンダーバーの位置をスライドさせて今どこにいるかわかりやすくすること可能でしょうか?

======================= 参考サイト ========================

1:CSSのみで実装可能
https://theorthodoxworks.com/web-design/moving-menu-bar-with-mouse-hover/

2:jsで実装可能
http://weblabla.m-pokoj.net/nav02/

======================= 追記 ========================
初心者マークの存在を知らず大変申し訳ありません。
教えていただきありがとうございました。
下記に記載されている内容でおおよそすべてかと思います。

一部記載内容に問題がある為削除しています。
・CSSのリンク
・画像のalt
・メニューボタンのリンクなど

また以下の記述は固定で変更不可です。
・<div id="Contents">
・<div class="GridSet">
・<div class="Grid4">
・<!--#include virtual="/ssi/footer.txt"-->

<!DOCTYPE html>
<html lang="ja">
<head>
<title></title>

<script type="text/javascript" src="jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="scroll.js"></script>

<link rel="index" title="" />
<link href="" type="text/css" rel="stylesheet" media="screen,print" />
</head>

<body>
<!-- ============== content_start ============= -->
<div id="Contents">
<div class="GridSet">
<div class="Grid4">

<div class="product">

<div id="header-fixed">
<div id="header-bk">
<a class="logo" href=""><img src=""></a>
<nav class="global-nav">
<p><a href="#top">Menu name</a></p>
<p><a href="#content_1">Menu name</a></p>
<p><a href="#content_2">Menu name</a></p>
<p><a href="#content_3">Menu name</a></p>
<p><a href="#content_4">Menu name</a></p>
<span class="global-nav--bar"></span>
</nav>
</div>
</div>

<main id="top">
<div id="content_1">
</div>

<div id="content_2">
</div>

<div id="content_3">
</div>

<div id="content_4">
</div>
</main>
<div class="Section">
<ul class="PageTop">
</ul>
</div><!--/Section-->

</div><!--/product-->

</div><!--/Grid4-->
</div><!--/GridSet-->
</div><!--/ContentsArea-->

<!--#include virtual="/ssi/footer.txt"-->
</body>
</html>
html{overflow-y: scroll;}

ul li{
    list-style-type: none;
}

img {
    border: 0px;
}

body {
    margin: 0;
    padding: 0;
    font-family: 'メイリオ',Meiryo,'ヒラギノ角ゴ Pro W3','Hiragino Kaku Gothic Pro','MS Pゴシック',sans-serif;
    color: #333;
    font-size: 100%;
    line-height: 100%;
    text-align: center;
    background-color:#333333;
    -webkit-text-size-adjust: 100%;
    line-height: 160%;
}

sup {
    margin: auto 1px auto;
    font-size: 92.2%;
    vertical-align: 0.15em;
    line-height: 100%;
}
* html body sup {font-size: 105%;}
*:first-child+html body sup {font-size: 105%;}

/*========== h3タグ設定 ==========*/
.title {
    margin:0 0 25px 0;
    padding:0;
    line-height:40px;
}

/*========== 画像中央配置 ==========*/
.img_center {
    display: block;
    margin-left: auto;
    margin-right: auto;
}

/*========== ヘッダー ==========*/
/* ヘッダーの固定 */
div#header-fixed {
    background-color:#000000;/* 背景色(黒) */
    position: fixed;/* ヘッダーの固定 */
    top: 0px;/* 位置(上0px) */
    left: 0px;/* 位置(右0px) */
    width: 100%;/* 横幅100%*/
    height: 50px;/* 縦幅140px */
} 

div#header-bk { 
    background-color:#000000;/* 背景色(黒) */
    margin:0 auto;
    padding:0;
    height:50px;/* 縦の高さ*/
    width:965px;/* 横の幅*/
}

/*========== ヘッダーボタン ==========*/
/* メニュー全体のスタイル */
.global-nav {
    position: relative;
    width: 100%;
    height: 50px;
    line-height: 20px;
    max-width: 720px;
    margin: 0;
    float: right;
}

/* 各メニューのスタイル */
.global-nav p {
    float: left;
    width: 20%;
}
.global-nav p a {
    display: block;
    color: #ffffff;
    text-decoration:none;
}

/* 黒いバーのスタイル */
.global-nav--bar {
    position: absolute;
    display: block;
    bottom: 0;
    left: 0;
    width: 20%;
    height: 5px;
    background: #ffffff;
    -webkit-transition: all .5s;
    transition: all .5s;
}

/* ホバーでバーの位置を変化 */
.global-nav p:nth-child(1):hover ~ .global-nav--bar {
    left: 0;
}
.global-nav p:nth-child(2):hover ~ .global-nav--bar {
    left: 20%;
}
.global-nav p:nth-child(3):hover ~ .global-nav--bar {
    left: 40%;
}
.global-nav p:nth-child(4):hover ~ .global-nav--bar {
    left: 60%;
}
.global-nav p:nth-child(5):hover ~ .global-nav--bar {
    left: 80%;
}

.logo{
    margin:0;
    padding:0;
    height:50px;
    width:200px;
    float:left;
}

/*========== メインコンテンツ基本設定 ==========*/
div.product {
    margin:0;
    padding:0;
    width:965px;
    display:inline-block;
    font-size:83%;
}

/*========== メイン ==========*/
main#top{
    background-color:#333333;
    margin:0;
    padding:80px 0 0 0;
}

/*========== メインコンテンツ ==========*/
div.top_img{
    margin:0;
    padding:0;
    width:965px;
    height:600px;
}

div#content_1 {
    margin:0 30px 0 30px;
    padding:60px 0 0 0;
    width:905px;
    height:500px;
}

div#content_2{
    margin:0 30px 0 30px;
    padding:60px 0 0 0;
    width:905px;
    height:500px;
}

div#content_3{
    margin:0 30px 0 30px;
    padding:60px 0 0 0;
    width:905px;
    height:500px;
}

div#content_4{
    margin:0 30px 0 30px;
    padding:60px 0 0 0;
    width:905px;
    height:500px;
}

div#content_5{
    margin:0 30px 0 30px;
    padding:60px 0 0 0;
    width:905px;
    height:500px;
}

/*========== 一覧 ==========*/

.item_box1 {
    margin:0;
    padding:0;
    width:905px;
    height:173px;
    font-size:0;
}

.item_box2 {
    margin:10px 0 0 0;
    padding:0;
    width:905px;
    height:173px;
    font-size:0;
}

.item1 {
    margin:0 10px 0 0;
    padding:0;
    width:173px;
    height:173px;
    line-height:173px;
    float: left;
}

.item2 {
    margin:0;
    padding:0;
    width:173px;
    height:173px;
    line-height:173px;
    float: left;
}

/*==========リンクボタン ==========*/
.button2 {
    margin:15px 0 0 0;
    padding:0px;
    background-color: #C4C4C4;
    color: #fff;
    display: inline-block;
    width:905px;
    height:35px;
    text-align: center;
    text-decoration: none;
    line-height:35px;
    outline: none;
}

.button:hover{
    background-color: #009933;
}

.button::before,
.button::after {
    position: absolute;
    z-index: -1;
    display: block;
    content: '';
}

.button,
.button::before,
.button::after{
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    -webkit-transition: all .3s;
    transition: all .3s;
}

/*========== フッター ==========*/
#Footer {
    clear: both;
    min-width: 965px;
    padding: 30px 0;
    background-color: #e5e5e5;
    overflow: hidden;
    clear:both;
}

#Footer h2 {
    margin: 0;
    padding: 0;
    border: none;
    line-height: 0;
    text-indent: -9999px;
}

#Footer ul {
    width: 965px;
    margin: 0 auto;
    font-size: 67%;
}

#Footer li {
    float: left;
    padding: 0 10px;
    border-left: solid 1px #bbb;
    line-height: 1.5em;
    vertical-align: top;
}
* html #Footer li {
    position: relative;
    z-index: 2;
}
*:first-child+html #Footer li {
    position: relative;
    z-index: 2;
}

#Footer li.FirstItem {
    padding: 0 10px 0 0;
    border-left: none;
}
#Footer li a:link,
#Footer li a:visited {
    color: #333;
    text-decoration: none;
}
#Footer li a:hover,
#Footer li a:active {
    color: #b1000e;
    text-decoration: underline;
}

#Footer p {
    width: 965px;
    margin: 0 auto;
    font-size: 65%;
    text-align: right;
    line-height: 1.5em;
    color: #333;
    vertical-align: top;
}
* html #Footer p {margin: -1.5em auto 0;}
*:first-child+html #Footer p {margin: -1.5em auto 0;}
$(function(){
   // #で始まるアンカーをクリックした場合に処理
   $('a[href^="#"]').click(function() {
      // スクロールの速度
      var speed = 400; // ミリ秒
      // アンカーの値取得
      var href= $(this).attr("href");
      // 移動先を取得
      var target = $(href == "#" || href == "" ? 'html' : href);
      // 移動先を数値で取得
      var position = target.offset().top;
      // スムーススクロール
      $('body,html').animate({scrollTop:position}, speed, 'swing');
      return false;
   });
});
<div id="Footer">
<h2</h2>
<ul>
<li class="FirstItem"><a href=""></a></li>
<li><a href=""></a></li>
<li><a href=""></a></li>
<li><a href=""></a></li>
</ul>
</div><!--/FooterArea-->

<!-- START OF SmartSource Data Collector TAG -->
<!-- Copyright (c)-->
<!-- Version: 9.4.0 -->
<!-- Tag Builder Version: 3.3  -->
<!-- Created:-->
<script src="/scripts/webtrends.js" type="text/javascript"></script>
<!-- ----------------------------------------------------------------------------------- -->
<!-- Warning: The two script blocks below must remain inline. Moving them to an external -->
<!-- JavaScript include file can cause serious problems with cross-domain tracking.      -->
<!-- ----------------------------------------------------------------------------------- -->
<script type="text/javascript">
//<![CDATA[
var _tag=new WebTrends();
_tag.dcsGetId();
//]]>
</script>
<script type="text/javascript">
//<![CDATA[
_tag.dcsCustom=function(){
// Add custom parameters here.
//_tag.DCSext.param_name=param_value;
}
_tag.dcsCollect();
//]]>
</script>
<noscript>
<div></div>
</noscript>
<!-- END OF SmartSource Data Collector TAG -->
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2017/07/10 11:43

    質問2つの要件が若干違うので検証しつつ回答に追記していきます。少々お待ちください。

    キャンセル

  • yuika39

    2017/07/10 11:48

    かしこまりました。よろしくお願い致します。

    キャンセル

  • m.ts10806

    2017/07/10 13:25

    質問内容についてざっくり検証したもので回答しました。参考にしてください。

    キャンセル

回答 1

checkベストアンサー

+2

 注記:

動作検証はある程度してはいるものの、あくまでサンプルであり最適解とは限りません。
自身の環境に導入するための参考程度にとどめておいてください。

質問1:

最後にマウスオーバーしたところにアンダーバーをとどめておくような設定は可能でしょうか?

hoverからoutしたときに戻ってしまうのはcssのhoverの特性だと思います。
hoverしたときのみに反映されるので、hoverしてない場合は初期値となります。

これを「hoverした箇所にとどめておく」はjavascriptとあわせることで可能です。
cssでhoverとアンダーバーの位置を指定しているところをマウスホバーイベントをjavascript側で取得し、
そのindexによってアンダーバーの位置を変えます。

    //グロナビhover時のイベントをキャッチ
    $('.global-nav p').on({
        'mouseenter' : function(){
            var index = $("p").index($(this));//何番目のpタグをマウスオーバーしたか取得
            var left_position = index * 20; //アンダーバーの位置を決定
            $(".global-nav--bar").css("left",left_position+"%"); //アンダーバー移動
            },
    });

javascriptが効いているのでcssはそのままでも動作はしますが(Chrome最新で確認)、
処理としては不要な記述となるのでhoverでアンダーバーの位置を動かしているcss記述は
コメントアウトするか、削除して無効にしておくことを推奨します。

質問2:

普通にマウスホイールでスクロールした場合それに合わせメニューのアンダーバーの位置をスライドさせて今どこにいるかわかりやすくすること可能でしょうか?

イメージは例えばCSSフレームワークのPushpinのようなものと推察されます。
Qiitaの記事とサブタイトルを連動してるやつも同じですね。
現在のスクロール位置と対象の記事のトップ位置をスクロール毎のイベントで取得し、比較してた上で
アンダーバーを移動させることで可能となると思います。

    $(window).scroll(function(){ //スクロール時のイベント
      var doc_pos = $(document).scrollTop(); //現在のスクロール位置を取得
        var left_position = 0;  
        if(doc_pos == 0){ //0の場合はTOPとする
            $(".global-nav--bar").css("left",left_position+"%");
        }else{
            for(i=1;i<5;i++){
                c_pos = $('#content_'+i).offset().top; //各コンテンツの位置を取得
                if(c_pos <= doc_pos){ //各コンテンツの位置を越えていたらアンダーバーを移動
                    left_position = i * 20;
                    $(".global-nav--bar").css("left",left_position+"%");
                }
            }
        }
   })

※ただし上記ソースは、グロナビメニュークリックでちょっとアンダーバーが横に動いて正位置に戻るような動作をします。
また「コンテンツは4つ(+トップ)」と決め打ちなので増減した場合に対応させる必要があります。
その部分を含めてご自身のサイトに合うように調整してみてください。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/07/10 14:30

    実装可能なコードのみではなく丁寧な解説までつけていただきとても分かりやすく大変感謝しております。
    自分のサイトに合わせ少し改良してみたいと思います。
    本当にありがとうございました!

    キャンセル

  • 2017/07/10 14:39

    解説というよりコードに書くコメントはもはや癖ですね。
    時間たってから見直したときに自分でもなぜこう書いたか分からなくなることはざらにあるので
    (「3日経てば他人のコード」というプログラマ格言があります。。。)
    少し未来の自身へ向けて書いたものでもあります。それで本当の他人が理解できればコメントとしては成功なので、
    こうやって喜んでもらえると自信がつきます。こちらこそありがとうございます。
    たぶんこれだけでは合わない部分も多々出てくると思うので、もしつまづいたり不明点がでてくれば、
    別途質問たてていただければと思います。
    がんばってください。

    キャンセル

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

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