iT邦幫忙

2024 iThome 鐵人賽

DAY 24
0

Sticky Nav

這次的功能非常實用,很多網站都有類似的效果。底下的導覽列,當使用者將視窗滾動到導覽列要消失在視窗的時候,導覽列就會釘在最上面。當你滾動回去時,它又會恢復。

https://ithelp.ithome.com.tw/upload/images/20241003/20169174vF23CQ5hg2.png

個人codepen

技巧點

1. offsetTop

  • 會得到此元素,相對於其父元素的頂部內邊距距離。在這邊的範例中,因為nav元素的父元素都沒有任何定位,所以指向body為父元素。因此offsetTop的距離就是,元素到視窗最上面的距離。
  • 注意!當元素定位後,會變成position: fixed; top: 0; left: 0,所以offsetTop會變回0。所以不能把offsetTop的取值放在fixNav的函式,不然,當他fixed之後,scrollY永遠都大於offsetTop...。就會變成此元素一直fixed狀態哈哈
  • 這邊也要注意nav元素原本是有佔位的,所以當nav變成fixed定位之後,他就不佔據空間了,底下的元素(site-wrap)自然就會往上跑。沒特別處理的話,就會出現(site-wrap)突然往上瞬間移動,被nav蓋住...。可以用body的paddingTop處理此狀況。
<div class="container">
  <header>
    <h1>LOGO</h1>
  </header>
  <nav>
    <ul>
      <li class="logo"><a href="#">LOGO</a></li>
      <li><a href="#">Home</a></li>
      <li><a href="#">About Us</a></li>
      <li><a href="#">Product</a></li>
      <li><a href="#">Blog</a></li>
      <li><a href="#">Contact Us</a></li>
    </ul>
  </nav>

  <div class="site-wrap">

    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
  </div>
</div>
const nav = document.querySelector("nav");

// 放在外面取值,確保offsetTop是固定的值,不被fixed影響
const navTop = nav.offsetTop;

function fixNav() 

// 判斷是否滾超過nav元素,是的話在整個body加上新的class,反之。
  if (window.scrollY >= navTop) {
    document.body.classList.add("fix-nav");
    // 有新的class之後,寫css去操作底下的nav讓他fixed
    
    // 處理nva元素不佔位後的問題
    document.body.style.paddingTop = nav.offsetHeight + "px";
  } else {
    document.body.classList.remove("fix-nav");
    document.body.style.paddingTop = 0;
  }
}
  • 影片中,有做了一個小小的縮放效果。操作上只是在css上加上scale,但是如果要有動畫效果就一定要使用transition。
.site-wrap {
  width: 500px;
  margin: 60px auto;
  background: white;
  padding: 40px;
  box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.3);
  transform: scale(0.99);
  transition: transform 0.3s;
}

  • 另外導覽列有隱藏的logo,也是藉由css的方式作出動畫。
// nav的每一個元素都用flex-grow讓他自動撐大,所以這邊用width:0會沒作用。所以限制最大高度,就可以達到縮放效果。
// 或者將logo設定flex-grow: 0,之後再讓他flex-grow: 1也可以。

nav ul li {
  flex: 1;
  text-align: center;
}
.logo {
  background: white;
  max-width: 0;
  /*   flex-grow: 0; */
  transition: 0.3s linear;
}

.fix-nav .logo {
  max-width: 300px;
  /*   flex-grow: 1; */
}

心得

前面操作了很多次dom元素的offset相關系列,這次就簡單多了。困難的應該是一開始你的html結構和css要怎麼設計比較好,畢竟會影響到你操作JS的行為~

影片的寫法一極棒,推薦學起來。


上一篇
Speech Synthesis
下一篇
Event Capture, Propagation, Bubbling and Once
系列文
鱷魚帶我練習JavaScript之個人練功坊29
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言