22 - Follow Along Link Highlighter 俗話說的好,一天一蘋果,醫生遠離我
一天一 JS,What the f*ck JavaScript?
small steps every day - 記錄著新手村日記
完成目標
功能
超連結Hover時,白色區塊要出現在該超連結區塊上
畫面
白色區塊的寬高要符合該超連結區塊
滑鼠進入另一個超連結區塊時,白色的區塊不會消失
index_START.html 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 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > 👀👀👀Follow Along Nav</title > <link rel ="stylesheet" href ="style.css" > </head > <body > <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 > <script > </script > </body > </html >
JS - step by step 首先,透過 querySelectorAll
將所有的 a 連結都找出來吧(這步驟應該很熟練了而且會是一個 NodeList(19) ),並且將帶有 Class highlight
的 span
附加在 body
上,這邊作者想表達的意思應該是可以透過 JS 來建立元素、新增Class 及寫進 HTML 之中
1 2 3 4 5 6 7 8 9 <script> const triggers = document .querySelectorAll('a' ); console .log(triggers); const highlight = document .createElement('span' ); console .log(highlight); highlight.classList.add('highlight' ); document .body.appendChild(highlight); </script>
接下來,每當使用者滑鼠移動到連結上就會觸發 mouseenter
事件,概念與 mouseover
大致相同,唯一的差別在於並不會冒泡
mouseenter:https://tinyurl.com/y6g3x4cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <script> const triggers = document .querySelectorAll('a' ); console .log(triggers); const highlight = document .createElement('span' ); console .log(highlight); highlight.classList.add('highlight' ); document .body.appendChild(highlight); function highlightLink ( ) { } triggers.forEach(a => a.addEventListener('mouseenter' , highlightLink)); </script>
當使用者觸發事件後,會呼叫 highlightLink
方法,其中會回傳 Element.getBoundingClientRect()
的 DOMRect 返回值對象,一組矩形的集合
Element.getBoundingClientRect():https://tinyurl.com/yyxcclg7
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <script> const triggers = document .querySelectorAll('a' ); console .log(triggers); const highlight = document .createElement('span' ); console .log(highlight); highlight.classList.add('highlight' ); document .body.appendChild(highlight); function highlightLink ( ) { const linkCoords = this .getBoundingClientRect(); console .log(linkCoords); } triggers.forEach(a => a.addEventListener('mouseenter' , highlightLink)); </script>
將回傳的長、寬、X軸、Y軸設為變數 coords
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <script> const triggers = document .querySelectorAll('a' ); console .log(triggers); const highlight = document .createElement('span' ); console .log(highlight); highlight.classList.add('highlight' ); document .body.appendChild(highlight); function highlightLink ( ) { const linkCoords = this .getBoundingClientRect(); console .log(linkCoords); const coords = { width: linkCoords.width, height: linkCoords.height, top: linkCoords.top + window .scrollY, left: linkCoords.left + window .scrollX }; } triggers.forEach(a => a.addEventListener('mouseenter' , highlightLink)); </script>
再當滑鼠滑到連結上時附加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 <script> const triggers = document .querySelectorAll('a' ); console .log(triggers); const highlight = document .createElement('span' ); console .log(highlight); highlight.classList.add('highlight' ); document .body.appendChild(highlight); function highlightLink ( ) { const linkCoords = this .getBoundingClientRect(); console .log(linkCoords); 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(a => a.addEventListener('mouseenter' , highlightLink)); </script>
就大功告成啦!
JS - final 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 <script> const triggers = document .querySelectorAll('a' ); console .log(triggers); const highlight = document .createElement('span' ); console .log(highlight); highlight.classList.add('highlight' ); document .body.appendChild(highlight); function highlightLink ( ) { const linkCoords = this .getBoundingClientRect(); console .log(linkCoords); 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(a => a.addEventListener('mouseenter' , highlightLink)); </script>
本刊同步於個人網站:http://chestertang.site/
本次範例程式碼原作者來源:https://tinyurl.com/yavm5f5n