iT邦幫忙

2

JS30 Day 21 & 22:Geolocation & Follow Along Link Highlighter學習筆記

今天兩個章節寫在一起,因為兩個份量都算較少,首先我們來分享Day21的章節。
此章節功能是利用Geolocation API,取得我們目前位置的經緯度、方向、速度等等,如下圖,當我們在移動時,會顯示我們的移動速度,且座標會依我們的移動方向做轉動,而由於隱私權關係,在使用前依然會詢問我們是否要開啟location,而此功能在Web裝置上較不常用,大多是使用在手機裝置上。

https://ithelp.ithome.com.tw/upload/images/20200730/20126182uMnfanSWJn.png

navigator.geolocation.getCurrentPosition():獲取當前的位置,只會觸發一次

navigator.geolocation.watchPosition():主要用於偵測移動中的位置,在移動時會一直觸發

navigator.geolocation.clearWatch() 這個函式是用來取消,Geolocation.watchPosition() 註冊的函式。

Geolocation Property:為Geolocation提供的一些屬性,可用來獲取我們所要的資料。

此處用到兩個屬性:

coords.heading:目前前進方向的角度,以北方為0度順時針計算。

coords.speed:目前的速度(公尺/秒)。


  <script>
    const arrow = document.querySelector('.arrow');
    const speed = document.querySelector('.speed-value');
    // navigator.geolocation.getCurrentPosition((position))
    // let watch = navigator.geolocation.watchPosition((data) 
    let watch = navigator.geolocation.watchPosition((data) => {
      console.log(data);
      speed.textContent = data.coords.speed;
      arrow.style.transform = `rotate(${data.coords.heading}deg)`;
    }, (err) => {
      console.error(err);
      navigator.geolocation.clearWatch(watch);
    });
  </script>

再來是Day22的部分,此章節要達到的功能就是當我們滑鼠移入至a標籤的字時,會對其字動態反白及一些樣式,而我們在這邊也分為區域性的移入樣式套用,及全域性的。

首先,我們在html部分新增一個span以來增添樣式至我們移入的字上。


  <nav>
    <ul class="menu">
      <!-- 設置一個highlight去將樣式套在我們滑鼠所移至的字 -->
      <span class="highlight"></span>
      <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>

在js部分,我們獲取所有在menu標籤為a的字,還有要反白的樣式span,並且將我們樣式先做隱藏。

      let target = document.querySelectorAll('.menu a');
      let highlight = document.querySelector('span');
      highlight.style.display = "none";

再來,對我們的字增添滑鼠移入的事件及函數。

      target.forEach((e) => {
        e.addEventListener('mouseenter', enterHandler)
      })

區域範圍(較常用到)

getBoundingClientRect:取得元素「相對於視窗」的座標,並回傳一個 DOMRect 物件,其中包含了x/y/width/height/top/right/bottom/left 等屬性。

當滑鼠移入時做函數處理,獲取當前移入字的位置、寬度、高度等,並利用style直接寫入,注意當我們滾動畫面時,因為top,left是以當前整個頁面的位置去做計算,因此會跑版,所以我們要改利用offsetTop/Left來獲取當前視窗離上面及左邊的距離,這樣即不會造成跑版。

      function enterHandler(e) {
        console.log(this.getBoundingClientRect());
        // DOMRect {x: 263.9750061035156, y: 100, width: 52.6875, height: 28.399999618530273, top: 100, …}
        let {
          width,
          height,
          top,
          left
        } = this.getBoundingClientRect();

        highlight.style.display = "";
        highlight.style.width = width + "px";
        highlight.style.height = height + "px";
        // highlight.style.top = top + "px";
        // highlight.style.left = left + "px";
        // 假如滾動頁面,利用offset就不會跑掉
        highlight.style.top = this.offsetTop + "px";
        highlight.style.left = this.offsetLeft + "px";

      }

全域範圍

而當我們想為全部a標籤的字做移入的處理,且在做視窗大小調整時,也不會跑版,首先要將我們的span移入至外層。

  <nav>
    <!-- 設置一個highlight去將樣式套在我們滑鼠所移至的字 -->
    <span class="highlight"></span>
    <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>

接著在js部分,我們新增一個now用來記錄當前指向的字。

      let now = null;
      let target = document.querySelectorAll('a');
      let highlight = document.querySelector('span');
      highlight.style.display = "none";

再來,我們對視窗大小的調整增添事件函數處理。

      // 當調整視窗大小時觸發,做RWD也能不跑版
      window.addEventListener('resize', setPosition)
      target.forEach((e) => {
        e.addEventListener('mouseenter', enterHandler)
      })

而滑鼠移入的事件函數處理,當我們移入時,就將當前的字this紀錄至now,並呼叫套用樣式的函數。

      function enterHandler() {
        // 紀錄當前移入的字
        now = this;
        setPosition();
      }

我們將套用樣式的函數,封裝起來做字位置及相關資料獲取,而在滾動頁面時,我們在top,left部分加上window.scrollY/X,也就是當前滾動的距離,這樣即可達到不會跑版的效果。

      function setPosition() {
        // 如果沒有移入字就跳出
        if (!now) return
        let {
          width,
          height,
          top,
          left
        } = now.getBoundingClientRect();

        highlight.style.display = "";
        highlight.style.width = width + "px";
        highlight.style.height = height + "px";
        // Window.scrollY / scrollX
        // 返回視窗在垂直/水平方向已滾動的像素值
        // 假如滾動頁面,利用原本的座標位置,再加上scrollX/Y就不會跑掉
        highlight.style.top = top + window.scrollY + "px";
        highlight.style.left = left + window.scrollX + "px";
      }

https://ithelp.ithome.com.tw/upload/images/20200730/20126182bhwr6PRCTg.png


尚未有邦友留言

立即登入留言