盤點JavaScript focus/blur(聚焦)實際應(yīng)用
大家好,我進階學習者。
一、前言
當用戶點擊某個元素或使用鍵盤上的 Tab 鍵選中時,該元素將會獲得聚焦(focus)。當網(wǎng)頁加載時,HTML-特性(attribute)。
autofocus也可以讓一個焦點落在元素上,不僅如此,還有其它途徑可以獲得焦點。
二、focus/blur 事件
當元素聚焦時,會觸發(fā) focus事件,當元素失去焦點時,會觸發(fā) blur事件。讓使用它們來校驗一個 input字段。
1. 案例分析
blur事件處理程序檢查這個字段是否輸入了電子郵箱,如果沒有輸入,則顯示一個 error。
focus事件處理程序隱藏 error 信息(在blur事件處理程序上會被再檢查一遍)。
2. 代碼
- <style>
- .invalid { border-color: red; }
- #error { color: red }
- </style>
- Your email please:
- <input type="email" id="input">
- <div id="error">
- </div>
- <script>
- input.onblur = function() {
- if (!input.value.includes('@')) { // not email
- input.classList.add('invalid');
- error.innerHTML = 'Please enter a correct email.'
- }
- };
- input.onfocus = function() {
- if (this.classList.contains('invalid')) {
- // 移除 "error" 指示,因為用戶想要重新輸入一些內(nèi)容
- this.classList.remove('invalid');
- error.innerHTML = "";
- }
- };
- </script>

注:
現(xiàn)代 HTML 允許使用 input特性(attribute),進行許多驗證:required,pattern等。
有時它們正是所需要的。當需要更大的靈活性時,可以使用 JavaScript。如果數(shù)據(jù)是正確的,可以把它自動發(fā)送到服務(wù)器。
三、focus/blur 方法
elem.focus()和 elem.blur()方法可以設(shè)置和移除元素上的焦點。
例:
如果輸入值無效,可以讓焦點無法離開這個 input字段:
- <body style="background-color: aqua;">
- Your email please:
- <input type="email" id="input">
- <input type="text" style="width:220px" placeholder="make email invalid and try to focus here">
- <script>
- input.onblur = function() {
- if (!this.value.includes('@')) { // not email
- // 顯示 error
- this.classList.add("error");
- // ...將焦點放回來
- input.focus();
- } else {
- this.classList.remove("error");
- }
- };
- </script>
- </body>

注:
如果在 input中輸入一些內(nèi)容,然后嘗試使用 Tab 鍵或點擊遠離 <input>的位置,那么 onblur事件處理程序會把焦點重新設(shè)置到這個 input字段上。
四、focus/blur 委托
focus和blur事件不會向上冒泡。
例如,不能把 onfocus放在 <form>上來對其進行高亮,像這樣:
- <!-- on focusing in the form -- add the class -->
- <form onfocus="this.className='focused'">
- <input type="text" name="name" value="Name">
- <input type="text" name="surname" value="Surname">
- </form>
- <style>
- .focused {
- outline: 1px solid red;
- }
- </style>
當用戶聚焦于 <input>時,focus事件只會在該 <input>上觸發(fā)。它不會向上冒泡。所以 form.onfocus永遠不會觸發(fā)。
form.onfocus永遠不會觸發(fā),(兩個解決方案)。
1. 方案一
有一個遺留下來的有趣的特性(feature):focus/blur不會向上冒泡,但會在捕獲階段向下傳播。
- <form id="form">
- <input type="text" name="name" value="Name">
- <input type="text" name="surname" value="Surname">
- </form>
- <style>
- .focused {
- outline: 1px solid red;
- }
- </style>
- <script>
- // 將處理程序置于捕獲階段(最后一個參數(shù)為 true)
- form.addEventListener("focus", () => form.classList.add('focused'), true);
- form.addEventListener("blur", () => form.classList.remove('focused'), true);
- </script>
2. 方案二
可以使用 focusin和 focusout事件 —— 與 focus/blur事件完全一樣,只是它們會冒泡。
注意:必須使用 elem.addEventListener來分配它們,而不是 on<event>。
所以,這是另一個可行的變體:
- <form id="form">
- <input type="text" name="name" value="Name">
- <input type="text" name="surname" value="Surname">
- </form>
- <style>
- .focused {
- outline: 1px solid red;
- }
- </style>
- <script>
- form.addEventListener("focusin", () => form.classList.add('focused'));
- form.addEventListener("focusout", () => form.classList.remove('focused'));
- </script>
一樣的結(jié)果:

五、總結(jié)
本文基于JavaScript基礎(chǔ),介紹了focus/blur(聚焦)實際應(yīng)用。通過事件以及對方法的講解。在元素獲得/失去焦點時會觸發(fā) focus和 blur事件,通過 document.activeElement來獲取當前所聚焦的元素。focus/blur 委托時遇到的問題,提供了兩個有效的解決方案。
歡迎大家積極嘗試,有時候看到別人實現(xiàn)起來很簡單,但是到自己動手實現(xiàn)的時候,總會有各種各樣的問題,切勿眼高手低,勤動手,才可以理解的更加深刻。
通過代碼的演示,運行效果圖的展示,能夠讓讀者更直觀的理解,更好的學習。
代碼很簡單,希望能夠幫助你更好的學習。