iT邦幫忙

2022 iThome 鐵人賽

DAY 23
1
自我挑戰組

在30天利用HTML & CSS & JavaScript完成Side Project實作系列 第 23

Day 23 Side Project : Verify Account UI 帳戶驗證介面

  • 分享至 

  • xImage
  •  


今天要來做的是很常見的用戶驗證介面


超白話畫面和功能拆解

  • 當輸入一個數字後,便會自動跳到下一個輸入框
  • 可以按backspace 按鍵去修改前面的數字

運用知識點羅列

  • CSS
知識點 使用說明
caret-color 設定光標顏色
:valid 選擇具有根據元素設置驗證的表單元素
  • JS
知識點 使用說明
focus( ) 自動把游標的焦點放到目標元素上,無須使用者再次操作
addEventListener( ) 使用"keydown"事件去監聽輸入框
setTimeout( ) 讓輸入框打完後會自動跳到下一格

流程講解

  • HTML
    每個輸入框,都有最小和最大值的限制
   <div class="container">
        <h2>Verify Your Account</h2>
        <p>...</p>
        <div class="code-container">
            <input type="number" class="code" placeholder="0" min="0" max="9" required>
            <input type="number" class="code" placeholder="0" min="0" max="9" required>
            <input type="number" class="code" placeholder="0" min="0" max="9" required>
            <input type="number" class="code" placeholder="0" min="0" max="9" required>
            <input type="number" class="code" placeholder="0" min="0" max="9" required>
            <input type="number" class="code" placeholder="0" min="0" max="9" required>
        </div>
    </div>
  • CSS
    大局配置
* {
  box-sizing: border-box;
}

body {
  background-color: #fbfcfe;
  margin: 0;
  padding: 0;
  display: flex; /*讓內容水平垂直置中*/
  justify-content: center;
  align-items: center;
  height: 100vh;
  overflow: hidden;
}

外部容器

.container {
  background-color: #fff;
  border: 3px #000 solid;
  border-radius: 10px;
  padding: 30px;
  max-width: 1000px;
  text-align: center;
}

密碼輸入

.code {
  caret-color: transparent; /*光標顏色*/
  border-radius: 5px;
  font-size: 75px;
  height: 120px;
  width: 100px;
  border: 1px solid #eee;
  margin: 1%;
  text-align: center;
  font-weight: 300;
}
.code:valid {
  border-color: #3498db;
  /* offset-x | offset-y | blur-radius | spread-radius | color */
  box-shadow: 0 10px 10px -5px rgba(0, 0, 0, 0.25);
}

以上都設定好,呈現如下
https://ithelp.ithome.com.tw/upload/images/20220929/20149362IBjn2rI0iu.png
加上沒有設置斷點,所以變成小視窗時,整個就會變形,所以要來解決這個問題
https://ithelp.ithome.com.tw/upload/images/20220929/20149362ypnNWmPfMx.png

RWD

@media screen and (max-width: 768px) {
  .code {
    font-size: 50px;
    height: 70px; /*原是120px*/
    width: 100px;
    max-width: 60px;
  }
}

  • JS
let codes = document.querySelectorAll(".code"); /*回傳NodeList,屬類陣列*/

codes[0].focus();

codes.forEach((code, idx) => {
  code.addEventListener("keydown", (e) => {
    console.log(e);
    if (e.key >= 0 && e.key <= 9) {
      setTimeout(() => codes[idx + 1].focus(), 10);
    } else if (e.key === "Backspace") {
      //B要大寫
      setTimeout(() => codes[idx - 1].focus(), 10);
    }
  });
});

分為以下幾點說明:

  • codes[0].focus() 代表滑鼠的光標會自動聚焦在第一格輸入框上
  • 使用addEventListener中的 keydown 事件去監聽輸入框,keydown可以監聽文字以外的按鍵(像是Tab、Esc、Backspace等),這是與 keypress 蠻不一樣的地方
  • 使用者在輸入時大致可以分為兩種輸入狀況:
    (1)輸入數字
    (2)輸入backspace(要刪除、修改時)
  • 可以看看完成圖,當我輸入了一個數字就會自動跳到下一個輸入框,這部分可以用 setTimeout 去完成(單位:毫秒),過了設定的時間後就去做要做的事

以上設定好後,呈現如下,有個bug就是當輸入backspace時,想修改數字,新的數字會皆在舊的數字後頭,但我不想要這樣,我想讓新的取代舊的可以怎麼做?

可以加入底下這段試試看,讓輸入框裡的值為空

codes[idx].value = "";

整段完整的code如下

let codes = document.querySelectorAll(".code"); /*回傳NodeList,屬類陣列*/

codes[0].focus();

codes.forEach((code, idx) => {
  code.addEventListener("keydown", (e) => {
    console.log(e);
    codes[idx].value = "";
    if (e.key >= 0 && e.key <= 9) {
      setTimeout(() => codes[idx + 1].focus(), 10);
    } else if (e.key === "Backspace") {
      //B要大寫
      setTimeout(() => codes[idx - 1].focus(), 10);
    }
  });
});

附上codepen連結 https://codepen.io/hangineer/pen/jOxZGax
今天就到這邊,若有解說不夠詳盡或是錯誤歡迎指教,感激不盡!那明天見囉


補充

  1. 比較 keydown, keypress, keyup 的差異
  2. 談談 JavaScript 的 setTimeout 與 setInterval

參考資料

50 Projects In 50 Days - HTML, CSS & JavaScript


上一篇
Day 22 Side Project : Hoverboard 面板
下一篇
Day 24 Side Project : Live User Filter 動態篩選器
系列文
在30天利用HTML & CSS & JavaScript完成Side Project實作30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言