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]