26 - Stripe Follow Along Nav
主題
製作一個隨著滑鼠移動展開的選單效果。
延續上次的練習JS30紀錄&心得」22 - Follow Along Link Highlighter,
這次用相同的原理來把效果製作成選單展開的形式。
步驟
Step1. 取得頁面元素與建立基本事件框架
取得頁面元素並分析此次效果僅有兩個事件mouseenter與mouseleave,
確定好知道目前要做的範圍,就先把function框建立好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   |  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));
 
  | 
 
Step2. 撰寫移入事件
編寫當滑鼠移入時被觸發的事件,備註如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
   |  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();
       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)`); }
 
  | 
 
Step3. 撰寫移出事件
簡單的移除被加上的class:
1 2 3 4
   | function handleLeave() {   this.classList.remove('trigger-enter', 'trigger-enter-active');   background.classList.remove('open'); }
  | 
 
其他
利用JS取得定位及大小資訊,並在適時置入對應元素中,
產生的動畫效果還得靠CSS,這練習主要是靠這兩個來產生效果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | .dropdownBackground {   width: 100px;   height: 100px;   position: absolute;   background: #fff;   border-radius: 4px;   box-shadow: 0 50px 100px rgba(50, 50, 93, .1), 0 15px 35px rgba(50, 50, 93, .15), 0 5px 15px rgba(0, 0, 0, .1);   transition: all 0.3s, opacity 0.1s, transform 0.2s;   transform-origin: 50% 0;   display: flex;   justify-content: center;   opacity: 0; }
  .dropdownBackground.open {   opacity: 1; }
  | 
 
[DEMO]