JS30 day22 Follow Along Links

Posted by Anthony Chao on 2019-11-23

JS30 day22 - Follow Along Links

作業內容

為什麼不是繼續寫 21 而是跳到 22 呢? 因為作業 21 需要哀鳳支援,這可能要稍微去借一下XD
今天的內容是要讓網頁的連結被指到的時候,出現白色背景,跟 hover 不同的是這個邊匡會在超連結之間移動!如果不明白我的意思可以看 CodePen 連結XD

學到什麼

  1. mouseentermouseover這兩個事件的差異在於 mouseenter 不支援事件冒泡
    這個例子可以了解

  2. getBoundingClientRect() 可以抓到綁定物件的 DOMRect 物件的長寬高座標等等資訊
    所以我們現在先可以做到右上角的 span 元素長寬高,會隨著我們指到的超連結變換長寬

1
2
3
4
5
function highlightLink(){
const linkCoords = this.getBoundingClientRect()
highlight.style.width = `${linkCoords.width}px`
highlight.style.height = `${linkCoords.height}px`
}
  1. 我們要怎麼移動這個 span 呢? 我們可以使用下面的方式
1
`highlight.style.transform = `translate(${linkCoords.left}px, ${linkCoords.top}px)`

所以整個 function 變成下面這樣子

1
2
3
4
5
6
function highlightLink(){
const linkCoords = this.getBoundingClientRect()
highlight.style.width = `${linkCoords.width}px`
highlight.style.height = `${linkCoords.height}px`
highlight.style.transform = `translate(${linkCoords.left}px, ${linkCoords.top}px)`
}

但這會有一個問題,一旦我們捲動螢幕,他的座標會跑掉,像下面這樣

這是因為沒有把捲動的座標考慮進來,使用 window.scrollX 還有 window.scrollY 來得到這個座標

1
2
3
4
5
6
7
8
9
10
11
12
13
function highlightLink(){
const linkCoords = this.getBoundingClientRect()
const coords = {
width: linkCoords.width,
height: linkCoords.height,
top: linkCoords.top + window.scrollY,
left: linkCoords.left + window.scrollX,
}

highlight.style.width = `${coords.width}px`
highlight.style.height = `${coords.height}px`
highlight.style.transform = `translate(${coords.left}px, ${coords.top}px)`
}

參考資料:
https://github.com/wesbos/JavaScript30

code 內容:
HTML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<nav>
<ul class="menu">
<li><a href="">Home</a></li>
<li><a href="">Order Status</a></li>
<li><a href="">Tweets</a></li>
<li><a href="">Read Our History</a></li>
<li><a href="">Contact Us</a></li>
</ul>
</nav>

<div class="wrapper">
<p>Lorem ipsum dolor sit amet, <a href="">consectetur</a> adipisicing elit. Est <a href="">explicabo</a> unde natus necessitatibus esse obcaecati distinctio, aut itaque, qui vitae!</p>
<p>Aspernatur sapiente quae sint <a href="">soluta</a> modi, atque praesentium laborum pariatur earum <a href="">quaerat</a> cupiditate consequuntur facilis ullam dignissimos, aperiam quam veniam.</p>
<p>Cum ipsam quod, incidunt sit ex <a href="">tempore</a> placeat maxime <a href="">corrupti</a> possimus <a href="">veritatis</a> ipsum fugit recusandae est doloremque? Hic, <a href="">quibusdam</a>, nulla.</p>
<p>Esse quibusdam, ad, ducimus cupiditate <a href="">nulla</a>, quae magni odit <a href="">totam</a> ut consequatur eveniet sunt quam provident sapiente dicta neque quod.</p>
<p>Aliquam <a href="">dicta</a> sequi culpa fugiat <a href="">consequuntur</a> pariatur optio ad minima, maxime <a href="">odio</a>, distinctio magni impedit tempore enim repellendus <a href="">repudiandae</a> quas!</p>
</div>

CSS:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
html {
box-sizing: border-box;
}

*, *:before, *:after {
box-sizing: inherit;
}

body {
min-height: 100vh;
margin: 0; /* Important! */
font-family: sans-serif;
background:
linear-gradient(45deg, hsla(340, 100%, 55%, 1) 0%, hsla(340, 100%, 55%, 0) 70%),
linear-gradient(135deg, hsla(225, 95%, 50%, 1) 10%, hsla(225, 95%, 50%, 0) 80%),
linear-gradient(225deg, hsla(140, 90%, 50%, 1) 10%, hsla(140, 90%, 50%, 0) 80%),
linear-gradient(315deg, hsla(35, 95%, 55%, 1) 100%, hsla(35, 95%, 55%, 0) 70%);
}

.wrapper {
margin: 0 auto;
max-width: 500px;
font-size: 20px;
line-height: 2;
position: relative;
}

a {
text-decoration: none;
color: black;
background: rgba(0,0,0,0.05);
border-radius: 20px;
}

.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);
}

.menu {
padding: 0;
display: flex;
list-style: none;
justify-content: center;
margin:100px 0;
}

.menu a {
display: inline-block;
padding: 5px;
margin: 0 20px;
color: black;
}

JS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const triggers = document.querySelectorAll('a')
const highlight = document.createElement('span')
highlight.classList.add('highlight')
document.body.append(highlight)

function highlightLink(){
const linkCoords = this.getBoundingClientRect()
const coords = {
width: linkCoords.width,
height: linkCoords.height,
top: linkCoords.top + window.scrollY,
left: linkCoords.left + window.scrollX,
}

highlight.style.width = `${coords.width}px`
highlight.style.height = `${coords.height}px`
highlight.style.transform = `translate(${coords.left}px, ${coords.top}px)`
}


triggers.forEach(trigger =>{
trigger.addEventListener('mouseenter', highlightLink)
})




prevent_hack