固定導覽列
當 scroll 超過 Nav 時,把 Nav fix 在最上方的效果。
主要流程:
window.scrollY
:已經 scroll 的距離element.offsetTop
:元素到頂端的距離加上事件監聽,監聽對象為 scroll
const nav = document.querySelector('#main') // 選擇 nav 的 id
const topOfNav = nav.offsetTop // 選擇 nav 到畫面頂端的距離
function fixNav() {
if(window.scrollY >= topOfNav) {
console.log(topOfNav, window.scrollY)
}
}
window.addEventListener('scroll', fixNav)
可以觀察 window.scrollY
以及 topOfNav
的變化
當 window.scrollY
超過 topOfNav
,加上 fix 的 CSS,反之則刪除
function fixNav() {
if(window.scrollY >= topOfNav) {
document.body.classList.add('fixed-nav')
} else {
document.body.classList.remove('fixed-nav')
}
}
.fixed-nav nav {
position: fixed;
box-shadow: 0 10px 10px 0px rgba(0, 0, 0, 0.5);
}
因為這邊 fix 的效果是先把 nav 從原本的畫面拿出,再固定到最上面,所以原本放置 nav 的位置會消失而由下面的元素遞補上去,造成畫面突然往上跳 (jerky jump) 的效果。
所以在跳動之前,我們可以同樣的加上一塊空白,讓原本 nav 的高度被填滿,使畫面不要往上跳躍。
這邊的做法是在 body 最上方加上 padding-top
填滿。
element.offsetHeight
:可以知道元素的高度(不包含 margin 的總高度,回傳為一整數)
function fixNav() {
if(window.scrollY >= topOfNav) {
document.body.classList.add('fixed-nav')
document.body.style['padding-top'] = `${nav.offsetHeight}px`
} else {
document.body.classList.remove('fixed-nav')
document.body.style['padding-top'] = 0
}
}
使用 position: sticky
的話就不會有 jerky jump 的問題,感謝 Allen 同學的補充~
不同於 position: fixed
,position: sticky
會「黏」在滾動過來的條列上並且保留原本的空間,並不是像 position: fixed
整個抽離離開畫面。
因為我們的 fixed-nav
是放在 body 上面,所以可以藉由是否有 fixed-nav
來實現以上這兩個效果
li.logo {
max-width: 0;
overflow: hidden;
background: white;
transition: all .5s;
font-weight: 600;
font-size: 30px;
}
.fixed-nav li.logo { // 如果有 fixed-nav 那 li.logo 便會出現
max-width: 200px;
}
.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{ // 如果有 fixed-nav 那 scale 就變大為 1
transform: scale(1);
}
offsetHeight MDN
返回元素的高度(不包含 margin 的總高度,回傳為一整數)
or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Do you want to remove this version name and description?
Syncing