Day22 Follow Along Nav

Demo

這次的主題是spotlight效果,我們預先設定好一個<span class="highlight"></span>在html裡
樣式在此範例已經幫我們做好了

1
2
3
4
5
6
7
8
9
10
11
12
.highlight {
transition: all 0.2s;
border-bottom:2px solid white;
position: absolute;
top:0;
background:white;
left:0;
z-index: -1;
border-radius:20px;
display: block;
box-shadow: 0 0 10px rgba(0,0,0,0.2);
}

主要的屬性就是絕對定位和z-index,而且先不給寬高。

作者是透過js創建<span class="highlight"></span>
我們也可以直接加在html上面就好了

對象和事件

會用到的對象和事件

1
2
3
4
5
6
const triggers = document.querySelectorAll('a');
const highlight = document.querySelector('.highlight');
function SpotLight(e){
//...
}
triggers.forEach(a=>a.addEventListener('mouseenter',SpotLight))

getBoundingClientRect()

透過新方法getBoundingClientRect
取得對象的大小換相對於視窗位置的資料,真的非常方便
詳細介紹

Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。

1
2
3
4
function SpotLight(e){
const targetInfo = e.target.getBoundingClientRect()
console.log(targetInfo)
}

印出取得的資料

取得資料

  1. DOMRect.top:元素於目前可視範圍中,距離上方邊界的距離。
  2. DOMRect.bottom:元素於目前可視範圍中,距離下方邊界的距離。
  3. DOMRect.left:元素於目前可視範圍中,距離左邊邊界的距離。
  4. DOMRect.right:元素於目前可視範圍中,距離右邊邊界的距離。
  5. DOMRect.x:元素於目前可視範圍中,水平方向的座標。
  6. DOMRect.y:元素於目前可視範圍中,垂直方向的座標。
  7. DOMRect.width:元素的寬。
  8. DOMRect.height:元素的高。


圖片來源:MDN

套用樣式

我們把寬高位置資料都取出後再套用在highlight上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function SpotLight(e){
const targetInfo = e.target.getBoundingClientRect()
//console.log(targetInfo)
//整理資料
const targetData = {
w: targetInfo.width,
h: targetInfo.height,
top: targetInfo.top,
left: targetInfo.left
}
highlight.style.width = `${targetData.w}px`
highlight.style.height = `${targetData.h}px`
highlight.style.transform = `translate(${targetData.left}px,${targetData.top}px)`
}

但出現一個小問題:

當我們捲動卷軸後,位置就錯誤了
所以我們在targetData資料的topleft要分別再加上window.scrollYwindow.scrollX
就大功告成囉!

程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const triggers = document.querySelectorAll('a');
const highlight = document.querySelector('.highlight');
function SpotLight(e){
const targetInfo = e.target.getBoundingClientRect()
//console.log(targetInfo)
//整理資料
const targetData = {
w: targetInfo.width,
h: targetInfo.height,
top: targetInfo.top + window.scrollY,
left: targetInfo.left + window.scrollX
}
highlight.style.width = `${targetData.w}px`
highlight.style.height = `${targetData.h}px`
highlight.style.transform = `translate(${targetData.left}px,${targetData.top}px)`
}

triggers.forEach(a=>a.addEventListener('mouseenter',SpotLight))
0%