## 緣起 在短網址的作業中,我想要新增一個頁面來讓使用者檢視產生過的短網址,並且在這個頁面也能針對每個短網址使用複製的功能 ## 第一次出手與失敗 第一次寫完之後發現,雖然每個button都有正常運作,但都只會複製到最後一筆資料,並不會複製到對應的資料 ```htmlmixed= <div class="row row-cols-1 row-cols-md-3 g-4"> {{#each urls}} <div class="col"> <div class="card h-100 ms-5 me-5"> <div class="card-body" id="card-body"> <h5 id="{{ _id }}" class="card-title">{{ shortenUrl }}</h5> <span class="card-text">{{ originalUrl }}</span> </div> <button class="btn btn-outline-secondary btn-sm" type="submit" onclick="copyUrl()"> <i class="fa-solid fa-copy"></i> </button> <script> function copyUrl () { const copyElement = document.getElementById({{ _id }}) const copyText = copyElement.textContent navigator.clipboard.writeText(copyText) alert("已複製: " + copyText) </script> </div> </div> {{/each}} </div> ``` ## 定義問題 打開DevTools發現因為迴圈的關係導致script被多次產生,所以button在被點擊時只會對應到最後一次產生的script。 ## 尋找與嘗試 一開始想說那我把script移出迴圈之外總可以了吧!變成下面這樣: ```htmlmixed= <div class="row row-cols-1 row-cols-md-3 g-4"> {{#each urls}} <div class="col"> <div class="card h-100 ms-5 me-5"> <div class="card-body" id="card-body"> <h5 id="{{ _id }}" class="card-title">{{ shortenUrl }}</h5> <span class="card-text">{{ originalUrl }}</span> </div> <button class="btn btn-outline-secondary btn-sm" type="submit" onclick="copyUrl()"> <i class="fa-solid fa-copy"></i> </button> </div> </div> {{/each}} <script> function copyUrl () { const copyElement = document.getElementById({{ _id }}) const copyText = copyElement.textContent navigator.clipboard.writeText(copyText) alert("已複製: " + copyText) </script> </div> ``` 結果這時候新的問題產生了...每個button都無法作用,再次打開DevTools檢查發現`document.getElementById({{ _id }})`竟然無法取得id,會變成`document.getElementById('')`導致無法複製的狀況產生。 這時的我非常困惑,不懂為什麼離開了迴圈之後程式就不知道{{ _id }}是甚麼了,在換了多個關鍵字搜尋之後還是沒有找到答案,可能是沒有使用到對的關鍵字吧。 於是,我就換個角度去搜尋,看看有甚麼方法可以去取得HTML標籤裡面屬性的值,讓我能順利的取得id。 ## 掌握關鍵,撥雲見月 在搜尋之後,我找到了[getAttribute()](https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute)這個方法,我開始著手修改程式碼成以下樣子: ```htmlmixed= <div class="row row-cols-1 row-cols-md-3 g-4"> {{#each urls}} <div class="col"> <div class="card h-100 ms-5 me-5"> <div class="card-body" id="card-body"> <h5 id="{{ _id }}" class="card-title">{{ shortenUrl }}</h5> <span class="card-text">{{ originalUrl }}</span> </div> <button class="btn btn-outline-secondary btn-sm" type="submit" onclick="copyUrl()"> <i class="fa-solid fa-copy"></i> </button> </div> </div> {{/each}} <script> function copyUrl () { // 在點擊button之後去取得h5標籤內id的值 const id = event.target.parentElement.children[0].children[0].getAttribute("id") const copyElement = document.getElementById(id) const copyText = copyElement.textContent navigator.clipboard.writeText(copyText) alert("已複製: " + copyText) } </script> </div> ``` 現在功能有按照我想要的樣子可以複製到每個button對應到的資料了,但還是存在著一點小問題,因為button標籤內還有著i標籤,如果使用者在圖案上點擊的話就會沒作用,所以需要再做一點小調整。 新增了if條件去判斷當使用者點擊在不同位置時,id取得的層次不同,確保使用者在button的範圍內點擊任意位置都能取得內容。雖然不知道能不能再優化,但目前能正常作用對我來說比較重要。 ```javascript= <script> function copyUrl () { if (event.target.tagName === "I") { const id = event.target.parentElement.parentElement.children[0].children[0].getAttribute("id") const copyElement = document.getElementById(id) const copyText = copyElement.textContent navigator.clipboard.writeText(copyText) alert("已複製: " + copyText) } else { const id = event.target.parentElement.children[0].children[0].getAttribute("id") const copyElement = document.getElementById(id) const copyText = copyElement.textContent navigator.clipboard.writeText(copyText) alert("已複製: " + copyText) } } </script> ``` ## 回顧與發現 雖然解決的過程看似很短,但其實也花了四、五個小時在解決這個小問題。一開始太執著於想要弄懂為什麼程式無法透過{{ _id }}來取得id,在解決不了問題的當下,就要開始尋找有沒有其他的可能性能解決問題,後續再回頭找答案。 ## 分享與展望 希望之後能找到更進一步優化的方式,未來還想嘗試看看在產生短網址時也產生一組QRcode的功能 完整版連結:[https://github.com/rz0585720/url_shortener](https://github.com/rz0585720/url_shortener)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up