恵比寿のWebサイト制作・Webデザインチームのブログ。Webデザインやコーディング、SEO対策まで幅広く手掛けています。

恵比寿のデザイン制作チームのブログです。

Webデザイン、
Web制作、
SEO対策の
ご依頼・ご相談

Contact

【JavaScript】スクロールすると特定の位置で追従するグローバルナビやヘッダーの実装方法

投稿日:2018-10-19 更新日:

今回は、特定の位置までスクロールすると、上からひょこっとグローバルナビやヘッダーが出てきて、そのまま追従する方法を紹介します。

文字で説明するよく分かりませんね。

百聞は一見に如かず。意味不明だと思った方は、下のデモをご覧ください。

こういう動きを取り入れているサイトはたまに見かけますね。

これをjQueryは使わず、HTML、CSS、生のJavaScriptで実装します。

特定の位置までスクロールする追いついてきて、上に固定されるメニューの実装方法

それでは、実装方法を書いていきます。

HTML

<header id="header" class="header">
  <nav class="global-nav" id="js-global-nav">
    <ul class="global-nav__list">
      <li><a href="">メニュー1</a></li>
      <li><a href="">メニュー2</a></li>
      <li><a href="">メニュー3</a></li>
      <li><a href="">メニュー4</a></li>
      <li><a href="">メニュー5</a></li>
    </ul>
  </nav>
</header><!-- /header -->

ポイントは、ナビに「js-global-nav」というidをふっているところです。

CSS

お次はCSSです。

.header {
  height: 50px;
  background-color: #fff;
  box-shadow: 0 2px 2px rgba(0,0,0,.2);
}
.global-nav {
  position: absolute;
  width: 100%;
  z-index: 10;
}
.global-nav__list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  justify-content: center;
}
.global-nav__list li {
  padding: 0 14px;
}
.global-nav__list li a {
  display: block;
  height: 50px;
  line-height: 50px;
  color: #111;
  text-decoration: none;
}
.global-nav.clone-nav {
  position: fixed;
  top: -100px;
  left: 0;
  transition: all 1s;
  background-color: #fff;
  box-shadow: 0 2px 2px rgba(0,0,0,.2);
}
.global-nav.clone-nav.is-fixed-nav {
  top: 0;
}

この段階では下のあたりのCSSはよく分からないと思います。そこはJavaScriptのコードの後に解説します。

JavaScript

/**
 * グローバルナビのクローンを生成
 */
function setCloneNav() {
  var body = document.body;
  var globalNav = document.getElementById('js-global-nav');

  if(!globalNav) return;

  var cloneNav = globalNav.cloneNode(true);
  cloneNav.id = 'js-clone-nav';
  cloneNav.classList.add('clone-nav');

  body.insertBefore(cloneNav, body.firstChild);
}
setCloneNav();

/**
 * グローバルナビのクローンをページ上部に移動・固定
 */
function fixedGlobalNav() {
  var scrollY = window.pageYOffset;
  var trigger = document.getElementById('js-trigger');
  var cloneNav = document.getElementById('js-clone-nav');

  if(!cloneNav || !trigger) return;

  var triggerClientRect = trigger.getBoundingClientRect();
  var triggerY = scrollY + triggerClientRect.top;
  if(scrollY > triggerY) {
    cloneNav.classList.add('is-fixed-nav');
  } else {
    cloneNav.classList.remove('is-fixed-nav');
  }
}
window.addEventListener('scroll', fixedGlobalNav);

最初の setCloneNav() は、グローバルナビを複製する関数です。

複製されたグローバルナビには、js-clone-navというidと、clone-navというclassを付けています。

上のCSS見ていただければ分かりますが、top: -100pxにして画面の外に隠しています。

二つ目の関数 fixedGlobalNav() は、id=”is-trigger”の位置までくるとメニューを表示させます。

id=”is-trigger” の位置まで来ると、.is-fixed-navが加わり、top:-100px → top: 0となり、上からにょきっと現れるのです。

要素が見つからない場合、処理を止める

上のJavaScriptのコードにある、

if(!globalNav) return;

と、

if(!cloneNav || !trigger) return;

は、要素がない場合それ以降の処理を止めるために記述します。

要素が見つからないのに、処理を進めるとエラーの原因になったり無駄なコードが動いたりするので、止めましょう。

まとめ

仕組みさえ分かってしまえば、結構簡単な処理です。

最初からfixedで固定させるより、あとから追従させた方が良い感じですね。

最後に、もう一度デモのリンクを貼っておきます。

Related Entries

この記事を書いた人

TAC

TAC

Webデザイナー、フロントエンドエンジニア。 Webデザイン、HTML/CSS、JavaScript、PHP、SEOが専門です。