ตัวอย่างโค้ด
สร้างแถบนำทางที่จะ "ติด" อยู่บนสุดจอภาพเมื่อผู้ใช้เลื่อนลงมาถึงตำแหน่งของ navbar โดยใช้ JavaScript ตรวจจับตำแหน่ง scroll และ CSS class สำหรับ fixed positioning
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sticky Navbar</title>
<style>
body {
margin: 0;
padding: 0;
height: 150vh; /* สร้างความสูงเพื่อทดสอบ scroll */
}
nav {
width: 100%;
background-color: rgb(39, 39, 39);
overflow: auto;
height: auto;
transition: all 0.3s ease;
}
.links {
display: inline-block;
text-align: center;
padding: 14px;
color: rgb(178, 137, 253);
text-decoration: none;
font-size: 17px;
}
.links:hover {
background-color: rgb(100, 100, 100);
}
.selected {
background-color: rgb(0, 18, 43);
}
/* Class สำหรับสถานะติดบนสุด */
.fixed {
position: fixed;
top: 0;
box-shadow: 0 2px 10px rgba(0,0,0,0.3);
z-index: 1000;
}
/* ป้องกันเนื้อหากระโดดเมื่อ navbar ติด */
.fixed + .sample-content {
padding-top: 60px; /* ความสูงของ navbar */
}
.sample-content {
padding: 20px;
}
</style>
</head>
<body>
<div class="sample-content">
<h1>หัวข้อก่อน Navbar</h1>
<h2>หัวข้อย่อย</h2>
<h3>หัวข้อย่อย</h3>
<h4>หัวข้อย่อย</h4>
</div>
<nav>
<a class="links selected" href="#"> หน้าแรก</a>
<a class="links" href="#"> เข้าสู่ระบบ</a>
<a class="links" href="#"> สมัครสมาชิก</a>
<a class="links" href="#"> ติดต่อเรา</a>
<a class="links" href="#"> ข้อมูลเพิ่มเติม</a>
</nav>
<div class="sample-content">
<h1>หัวข้อหลัง Navbar</h1>
<h2>หัวข้อย่อย</h2>
<h3>หัวข้อย่อย</h3>
<h4>หัวข้อย่อย</h4>
</div>
<script>
const navEle = document.querySelector("nav");
const stickyTop = navEle.offsetTop;
function scrollShowNav() {
if (window.pageYOffset >= stickyTop) {
navEle.classList.add("fixed");
} else {
navEle.classList.remove("fixed");
}
}
window.addEventListener('scroll', scrollShowNav);
</script>
</body>
</html>
การทำงาน
- Navbar เริ่มต้นอยู่ในตำแหน่งปกติ (static) ตามลำดับเอกสาร
- เมื่อ scroll ลงมาถึงตำแหน่ง
navEle.offsetTopจะเพิ่ม class.fixed - Class
.fixedทำให้ navbar กลายเป็นposition: fixed; top: 0 - Selector
.fixed + .sample-contentเพิ่ม padding-top ป้องกันเนื้อหากระโดดขึ้น
เทคนิคสำคัญ
- offsetTop - เก็บตำแหน่งเดิมของ navbar เทียบกับ document
- window.pageYOffset - ตำแหน่ง scroll ปัจจุบัน
- classList.add/remove - จัดการ class แบบทันสมัย
- Transition - ทำให้การเปลี่ยนแปลงดูนุ่มนวล
วิธีทันสมัยกว่า: CSS position: sticky
nav {
position: sticky;
top: 0;
z-index: 1000;
/* ไม่ต้องใช้ JavaScript เลย! */
}
หมายเหตุ: position: sticky รองรับในเบราว์เซอร์สมัยใหม่ทุกตัว และประหยัดประสิทธิภาพมากกว่า JavaScript scroll listener
ข้อควรพิจารณา
- ประสิทธิภาพ: ใช้
requestAnimationFrameหรือIntersectionObserverแทน scroll event โดยตรง - Padding-top compensation: คำนวณความสูง navbar จริงด้วย
navEle.offsetHeight - z-index: ตั้งค่าให้เพียงพอไม่ให้ถูกปิดบัง