iT邦幫忙

2023 iThome 鐵人賽

DAY 24
0
Modern Web

JS30 x 鐵人30 x MDN doc系列 第 24

[Day24] - Sticky Nav(JS30 x 鐵人 30 x MDN)

  • 分享至 

  • xImage
  •  

將 nav-bar 固定於網頁上方

要 nav-bar 在視窗滑動超過於自己時固定頂端有兩種方式,作者使用position:fixed,但會照成自己脫離文檔流,所佔用空間完全消失,因此設定為 fixed,還要將 nav 的容器本身高度加回去才不會產生跑版的問題,那position:sticky就聰明許多是根據其祖先元素的滾動情況來決定是否固定,以及在何處固定。這使得 position: sticky; 更加靈活,可以根據需要在不同情況下進行動態調整,因此我這邊選用 sticky 寫法。

  1. 改寫 css
nav {
  /* 將position改為sticky其他維持不變 */
  position: sticky;
}
  1. 新增捲動到 nav sticky 時其他要變更的 css 樣式
/* 文章內文取消縮小,變回原比例 */
.sticky-nav .site-wrap {
  transform: scale(1);
}
/* 隱藏的logo要出現(原寬度為0) */
.sticky-nav li.logo {
  max-width: 500px;
}
  1. 針對視窗新增滾動事件監聽器,當滾動超過 nav 頂點時,在 body 掛上sticky-navclass 表示這時候 nav 已經固定於頁面頂端,第二點設定的那些樣式也會套用,反之則移除 class,考量到 Day22 學習到的可能外層結構有 relative 造成 offsetParent 不是 body 因此判斷的地方我改用Element: getBoundingClientRect()的 y 屬性,當期小於零則表示頁面以滾動超過元素
//  取得nav-bar節點
const nav = document.querySelector("nav");
//  針對視窗新增滾動事件監聽器
window.addEventListener("scroll", stickyNav);

function stickyNav() {
  //  當滾動超過nav頂點時
  if (0 >= nav.getBoundingClientRect().y) {
    //  在body掛上`sticky-nav`class
    document.body.classList.add("sticky-nav");
    //  反之則移除class
  } else {
    document.body.classList.remove("sticky-nav");
  }
}

👉Github Demo 頁面 👈

👉 好想工作室 15th 鐵人賽看板 👈

參考資料

  1. Javascript 30 官網
    https://javascript30.com/
  2. MDN 官網
    https://developer.mozilla.org/en-US/

上一篇
[Day23] - Speech Synthesis(JS30 x 鐵人 30 x MDN)
下一篇
[Day25] - Event Capture, Propagation, Bubbling and Once(JS30 x 鐵人 30 x MDN)
系列文
JS30 x 鐵人30 x MDN doc30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言