iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0

26 - Stripe Follow Along Nav

tags: JavaScript30

專案簡介

第二十六天要實作的專案是延續第二十二天實作的內容

課程影片:JS30 26
導讀影片:Alex

初始文件

Github 檔案位置:26 - Stripe Follow Along Nav

網站的樣子

可以先看看最後的成果

正式製作

首先,一樣先選取要操作的元素、設定好監聽

const triggers = document.querySelectorAll('.cool > li');
const background  = document.querySelector('.dropdownBackground');
const nav  = document.querySelector('.top');

function handleEnter() {

}

function handleLeave() {
 
}

triggers.forEach(trigger => trigger.addEventListener('mouseenter', handleEnter));
triggers.forEach(trigger => trigger.addEventListener('mouseleave', handleLeave));

接下來先加入文字的動畫效果,使游標移到導覽列時會列出內容,離開時消失

備註:this.classList.contains('trigger-enter') 可以避免快速的切換時文字內容有殘留

備註:在 setTimeout() 中要使用箭頭函示繼承 this,否則會指向 window

function handleEnter() {
  this.classList.add('trigger-enter');
  setTimeout(() => this.classList.contains('trigger-enter') && this.classList.add('trigger-enter-active'), 150);
}

function handleLeave() {
  this.classList.remove('trigger-enter', 'trigger-enter-active'); 
}

再來就是實作之前做過的白色背景跟蹤的效果了,首先先抓取會利用到的各元素,再計算出白色背景的座標及大小並賦值

備註:在選取 dropdown 時要使用 this,因為三者的座標及長寬是不同的

備註:計算座標時要減掉 nav 的大小,否則會像下面這樣

修正後如下

function handleEnter() {
  // ...
  background.classList.add('open');

  const dropdown = this.querySelector('.dropdown');
  const dropdownCoords = dropdown.getBoundingClientRect();
  const navCoords = nav.getBoundingClientRect();
  console.log(dropdown);
	
  const coords = {
    height: dropdownCoords.height,
    width: dropdownCoords.width,
    top: dropdownCoords.top - navCoords.top,
    left: dropdownCoords.left - navCoords.left
  };
	
  background.style.setProperty('width', `${coords.width}px`);
  background.style.setProperty('height', `${coords.height}px`);
  background.style.setProperty('transform', `translate(${coords.left}px, ${coords.top}px)`);
}

最後程式碼

const triggers = document.querySelectorAll('.cool > li');
const background  = document.querySelector('.dropdownBackground');
const nav  = document.querySelector('.top');

function handleEnter() {
  this.classList.add('trigger-enter');
  setTimeout(() => this.classList.contains('trigger-enter') && this.classList.add('trigger-enter-active'), 150);
  background.classList.add('open');

  const dropdown = this.querySelector('.dropdown');
  const dropdownCoords = dropdown.getBoundingClientRect();
  const navCoords = nav.getBoundingClientRect();
  console.log(dropdown);

  const coords = {
    height: dropdownCoords.height,
    width: dropdownCoords.width,
    top: dropdownCoords.top - navCoords.top,
    left: dropdownCoords.left - navCoords.left
  };

  background.style.setProperty('width', `${coords.width}px`);
  background.style.setProperty('height', `${coords.height}px`);
  background.style.setProperty('transform', `translate(${coords.left}px, ${coords.top}px)`);
}

function handleLeave() {
  this.classList.remove('trigger-enter', 'trigger-enter-active');
  background.classList.remove('open');
}

triggers.forEach(trigger => trigger.addEventListener('mouseenter', handleEnter));
triggers.forEach(trigger => trigger.addEventListener('mouseleave', handleLeave));

完成結果

最後的成品

結語

以上是第二十六天的製作紀錄,如有錯誤或不足的地方還請多多指教 >.<

Stripe Follow Along Dropdown Navigation - #JavaScript30 26/30
[ Alex 宅幹嘛 ] ?‍? 深入淺出 Javascript30 快速導覽 | Day 26:Stripe Follow Along Nav
MDN Web Docs


上一篇
JS30 -> 25 - Event Capture, Propagation, Bubbling and Once
下一篇
JS30 -> 27 - Click and Drag
系列文
剛接觸前端一個月的小白 - JavaScript30 挑戰筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言