iT邦幫忙

2022 iThome 鐵人賽

DAY 24
0
自我挑戰組

JavaScript 30天挑戰 自學筆記系列 第 24

JS30 自學筆記 Day24_Sticky Nav

  • 分享至 

  • xImage
  •  

今日任務: 將選單釘選在上方

當捲動的大小>= 選單到頂部的大小,將選單fixed


Day13有學過:
window.scrollY: 從頂部開始捲軸已捲動的長度,別名window.pageYOffset
offsetTop是元素本身相對於offsetParent的垂直距離。
offsetParent是與元素最近的,有被定位(position不等於static)的父層。

注意: 以下情況offsetParent 會回傳 null:

  • 元素或其父元素的display屬性設置為 none。
  • 該元素的position屬性設置為fixed (Firefox 返回)。
  • 元素是或。

捲動後nav會將position設定為fixed,這時offsetParent會變null,nav.offsetTop會變成0,window.scrollY 會一直大於 nav.offsetTop,會沒有作用。
所以一開始就先宣告const topOfNav = nav.offsetTop;,得到nav到body頂部的垂直距離。

const nav = document.querySelector('#main');
const topOfNav = nav.offsetTop;

window.addEventListener('scroll', fixNav);

function fixNav() {
    if (window.scrollY >= topOfNav) {
        document.body.classList.add('fixed-nav');
    } else {
        document.body.classList.remove('fixed-nav');
    }
}

CSS

box-shadow

box-shadow:inset offset-x offset-y blur-radius spread-radius 陰影顏色;

  • inset:用來設定內陰影,選擇性項目,無填寫代表呈現為外陰影。
  • offset-x:x 軸方向的陰影大小,單位為長度單位,如 em、px 等。
  • offset-y:y 軸方向的陰影大小,單位為長度單位,如 em、px 等。
  • blur-radius:模糊半徑,選擇性項目,未填寫則為預設值零。
  • spread-radius:擴散半徑,選擇性項目,未填寫則為預設值零。
  • 陰影顏色:必要項目,自行決定陰影的顏色。
.fixed-nav nav {
    position: fixed;
    /*box-shadow: x y 模糊 顏色;*/
    box-shadow: 0 10px 10px #3333;
}

body加padding

當捲動時,畫面會跳動,
因為當被fixed,選單就不再佔位子,會浮出畫面,下面的div就會往上移


所以我們要在body加padding,佔住一個位子給選單

function fixNav() {
    if (window.scrollY >= topOfNav) {
        document.body.classList.add('fixed-nav');
        document.body.style.paddingTop = nav.offsetHeight + 'px';
    } else {
        document.body.classList.remove('fixed-nav');
        document.body.style.paddingTop = 0;
    }
}

選單裡的logo

當選單釘選上方時(.fixed-nav),將logo的max-width改為200px,就可以有logo滑出的效果(寬度從0到200px)。
使用max-width才能有transition動畫效果,width沒有。

透過在父層加一個class名稱,剩下的交給CSS選取器,子元素就可以一起有變化效果。

li.logo {
    max-width: 0;
    overflow: hidden;
    background: white;
    transition: all 0.5s;
    font-weight: 600;
    font-size: 30px;
}

.fixed-nav li.logo {
    max-width: 200px;
}

內容也可以放大

transform: scale(0.98);=>transform: scale(1);

.site-wrap {
    max-width: 700px;
    margin: 70px auto;
    background: white;
    padding: 40px;
    text-align: justify;
    box-shadow: 0 0 10px 5px rgba(0, 0, 0, 0.05);
    transform: scale(0.98);
    transition: transform 0.5s;
}

.fixed-nav .site-wrap {
    transform: scale(1);
}

今日學習到的:

  • 透過在父層加一個class名稱,剩下的交給CSS選取器,子元素就可以一起有變化效果。
  • 以下情況offsetParent會回傳 null:
    • 元素或其父元素的display屬性設置為 none。
    • 該元素的position屬性設置為fixed (Firefox 返回)。
    • 元素是或。
  • box-shadow:(設定內陰影) x位移 y位移 (模糊半徑) (擴散半徑) 顏色;
  • 使用max-width才能有transition動畫效果,width沒有。

效果連結:連結

參考連結:
wibibi: CSS3 box-shadow
MDN: HTMLElement.offsetParent


上一篇
JS30 自學筆記 Day23_Speech Synthesis
下一篇
JS30 自學筆記 Day25_Event Capture, Propagation, Bubbling and Once
系列文
JavaScript 30天挑戰 自學筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言