91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue中怎么實現回車鍵切換焦點

發布時間:2021-05-09 15:34:32 來源:億速云 閱讀:618 作者:小新 欄目:web開發

這篇文章主要介紹了Vue中怎么實現回車鍵切換焦點,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

vue是什么

Vue是一套用于構建用戶界面的漸進式JavaScript框架,Vue與其它大型框架的區別是,使用Vue可以自底向上逐層應用,其核心庫只關注視圖層,方便與第三方庫和項目整合,且使用Vue可以采用單文件組件和Vue生態系統支持的庫開發復雜的單頁應用。

幾乎在所有瀏覽器中,都具有 Tab 鍵切換焦點的功能。

但是任性的用戶強烈要求一定要有 Enter 鍵切換焦點的功能。

為了交付上線拿到錢,我們只好再一次毫無原則性的接受了客戶的需求。

在上一代人中,大多都有這種操作習慣。習慣把保存成為編輯,習慣用回車替換 Tab。這是受到微軟 excel 荼毒的結果。

起初我以為這個功能很簡單,無非就是把 Enter 鍵的功能轉接到 Tab 鍵上面,分分鐘就可以解決掉的問題。

可困難馬上就出現了,我發現這條路是走不通的。

我們經常可以主動觸發某個事件,比如 el.click() 就可以調用點擊事件,或者使用 dispatchEvent 。但是鍵盤和鼠標事件卻不行。

我查閱了很多資料,也做了很多嘗試。最后總結出來一個結論,在瀏覽器中,JavaScript 無法操作用戶的鍵盤或者鼠標,這是出于安全策略的考慮。仔細想一下,如果可以用一段 JavaScript 腳本控制用戶鍵盤和鼠標的話,那么用戶只需要打開一個黑客網站,黑客就可以瞬間得到他想得到的一切。

所以,如果要通過除 Tab 鍵以外的其他方式來觸發焦點切換, focus 幾乎是唯一的選擇。

在原生頁面中實現回車鍵切換焦點

項目是基于 vue 和 element-ui 做的,為了把實現思路先講清楚,暫時把這些拋開,從原生的頁面中尋找答案。

以下是一個原生的 html 頁面。

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8" />
 <meta name="viewport" content="width=device-width" />
 <title>Demo</title>
 </head>
 <body>
 <form>
 <input placeholder="姓名" />
 <input placeholder="性別" />
 <input placeholder="年齡" />
 </form>
 </body>
</html>

接下來要實現通過回車鍵切換焦點,我把思路梳理如下:

  1. 監聽回車鍵按下事件。

  2. 獲取當前聚焦元素。

  3. 獲取下一個要被聚焦的元素。

  4. 切換焦點。

思路有了,實現起來也非常簡單。

1.監聽回車鍵按下事件

在文檔中添加 script 標簽,寫入如下代碼。

function enterCallback(e) {
 if (e.keyCode === 13) {
 // 按下回車后的邏輯
 }
}
window.addEventListener("keydown", enterCallback);

要注意, enterCallback 單獨拿出來,用于注銷監聽事件。

監聽按鍵事件最常用的方法就是使用事件委托,將事件綁定到 window 對象上。相比較給每一個元素都綁定一個事件的方式,這樣做的最大好處就是節省內存空間,性能更好。

判斷按下哪個鍵的方式有很多,比如判斷 e.keye.code 或者 e.keyCode 等方式。但絕大多數的情況下都建議使用 e.keyCode 。下面是一張來自網絡的 keyCode 表。

Vue中怎么實現回車鍵切換焦點

2.獲取當前聚焦元素

很容易就可以做到這一步。

常見的有兩種方式。第一種是 e.target ,第二種是 document.activeElement 。這種情況下,個人更推薦使用第二種。

function enterCallback(e) {
 if (e.keyCode === 13) {
 let activeEl = document.activeElement;
 }
}

3.獲取下一個要被聚焦的元素

這一步也比較容易。使用 el.nextElementSibling API 即可獲取。

function enterCallback(e) {
 if (e.keyCode === 13) {
 let activeEl = document.activeElement;
 let nextEl = activeEl.nextElementSibling;
 }
}

4.切換焦點

切換焦點調用 focus 即可實現。

function enterCallback(e) {
 if (e.keyCode === 13) {
 let activeEl = document.activeElement;
 let nextEl = activeEl.nextElementSibling;
 nextEl && nextEl.focus();
 }
}

至此一個最簡單的 Demo 已經實現了,接下來看看項目中實際的情況。

在 element-ui 項目中實現回車鍵切換焦點

因為是使用組件開發,加上樣式等因素,dom 節點并不像上面寫的原生 Demo 那么簡單,實際情況是多層嵌套的。下面是實際生成的代碼結構。

<div
 class="el-form-item el-form-item--small"
 
>
 <label for="pactcode" class="el-form-item__label" 
 >協議號</label
 >
 <div class="el-form-item__content" >
 <div class="el-input el-input--small">
 <!---->
 <input
 type="text"
 autocomplete="off"
 id="el-input"
 placeholder="未填寫協議號"
 class="el-input__inner"
 />
 <!---->
 </div>
 </div>
</div>

可以看到,如果每一個輸入框都是這種類型的嵌套結構,上面的方法是無法直接解決的。因為 nextElementSibling API 只能找到下一個兄弟元素,而在這里 input 明顯找不到下一個兄弟元素。

思路是,通過回溯的手段朝外層尋找,直到找到一個類名包含 el-form-itemel-form-item--small 的祖級元素,然后再從這個祖級元素的下一個兄弟元素中尋找類名包含 el-input__inner 的 input 元素。

所以要再寫兩個函數,分別是尋找組件元素的 findFormItem 和尋找 input 元素的 findInput

findFormItem:

function findFormItem(el) {
 const parent = el.parentElement;
 if (!parent) return document.body;
 if (
 parent.className.includes("el-form-item") &&
 parent.className.includes("el-form-item--small")
 ) {
 return parent;
 }
 return findFormItem(parent);
}

findInput:

function findInput(container) {
 let nextEl = container.nextElementSibling;
 if (!nextEl) return;
 let input = nextEl.querySelector("input");
 while (input.id === "el-select") {
 nextEl = nextEl.nextElementSibling;
 if (!nextEl) return;
 input = nextEl.querySelector("input");
 }
 if (input.className.includes("el-input__inner")) return input;
}

有了這兩個函數以后,實現回車切換焦點就非常簡單了。只需要執行兩行代碼。

const container = findFormItem(document.activeElement);
findInput(container) && findInput(container).focus();

完整的代碼大概是這樣的。

methods 中聲明三個方法。

methods: {
 addEnterListener() {
 if (window.__completeEnterBind__) return;
 window.addEventListener("keydown", this.enterCallback);
 window.__completeEnterBind__ = true;
 },
 removeEnterListener() {
 window.removeEventListener("keydown", this.enterCallback);
 window.__completeEnterBind__ = false;
 },
 enterCallback(e) {
 function findFormItem(el) {
 const parent = el.parentElement;
 if (!parent) return document.body;
 if (
  parent.className.includes("el-form-item") &&
  parent.className.includes("el-form-item--small")
 ) {
  return parent;
 }
 return findFormItem(parent);
 }
 function findInput(container) {
 let nextEl = container.nextElementSibling;
 if (!nextEl) return;
 let input = nextEl.querySelector("input");
 while (input.id === "el-select") {
  nextEl = nextEl.nextElementSibling;
  if (!nextEl) return;
  input = nextEl.querySelector("input");
 }
 if (input.className.includes("el-input__inner")) return input;
 }
 if (e.keyCode === 13) {
 const container = findFormItem(document.activeElement);
 findInput(container) && findInput(container).focus();
 }
 }
}

然后在 mounted 中添加回車監聽和在 destroy 中移除回車鍵聽。

mounted() {
 this.addEnterListener();
},
destroy() {
 this.removeEnterListener();
},

需要注意的是,項目是多標簽頁的形式,表單組件可能會被渲染多次,所以通過在 window 對象上添加一個 __completeEnterBind__ 字段來確保回車換行事件正確綁定。

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Vue中怎么實現回車鍵切換焦點”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

vue
AI

迭部县| 阿巴嘎旗| 牟定县| 奉化市| 台前县| 象州县| 修武县| 大余县| 本溪| 双流县| 湖北省| 泰和县| 奈曼旗| 平定县| 东明县| 金山区| 佛冈县| 屏边| 龙海市| 秦安县| 永和县| 贞丰县| 探索| 广西| 承德市| 富阳市| 南昌县| 伊金霍洛旗| 南汇区| 盱眙县| 娄烦县| 正宁县| 望城县| 肥乡县| 波密县| 孟津县| 兴和县| 隆安县| 阜南县| 仲巴县| 鞍山市|