提問:
鍵盤默認事件,比如tab切換,alt+f4關閉,ctrl+t新建等,如果不想通過鍵盤而是一些按鈕點擊來觸發這些功能,該咋辦呢?
例子:
先以tab為例上一個小例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>觸發鍵盤默認事件</title>
</head>
<body>
<div>
<input type="button" tabindex="-1" value="點點點點點" id="btn">
<input type="text" placeholder="1">
<input type="text" placeholder="2">
<input type="text" placeholder="3">
<input type="text" placeholder="4">
<input type="text" placeholder="5">
<input type="text" placeholder="6">
</div>
<script>
// 當前獲取焦點的元素
var nowEle=document; // 需要焦點切換的元素
var inputs=[].slice.call(document.querySelectorAll("[type=text]")); // 只添加獲取焦點事件
// 放棄失去焦點事件 -- 需要判斷失去后焦點被誰獲得,太麻煩
inputs.forEach(function(el,i){ el.onfocus=function(){ nowEle=this; }; /*el.onblur=function(){ setTimeout(function() { nowEle=document; }, 0); };*/ }); // !!! 關鍵部分,事件模擬 !!!
btn.onclick=function(ev){ // console.log(nowEle);
var e=document.createEvent("KeyboardEvents"); e.initKeyboardEvent("keydown",true,true,window,"U+0009"); // tab
if(nowEle==inputs[inputs.length-1])nowEle=document; nowEle.focus && nowEle.focus(); nowEle.dispatchEvent(e); // console.log(e);
}; /*document.onkeydown=function(ev){ // console.log(ev.keyCode,ev.which,ev); };*/
// input獲取焦點:tab切換和鼠標點擊
// 這里處理鼠標點擊獲取焦點
document.addEventListener("click",function(ev){ for (var i = 0; i < inputs.length; i++) { if(inputs[i]==ev.target || btn==ev.target)return; }; nowEle=document; },false); </script>
</body>
</html>
介紹:
實際效果:模擬tab事件在指定范圍內移動焦點,點擊按鈕,使焦點在6個input標簽里切換。
主邏輯為:通過鍵盤事件和點擊事件(焦點的兩種獲取方式)找到當前獲取焦點的元素,通過按鈕點擊來模擬鍵盤的tab按鈕。
技術難點:鍵盤事件模擬,以及找到正確的事件觸發者。
難點:
模擬鍵盤事件:
var e=document.createEvent("KeyboardEvents"); e.initKeyboardEvent("keydown",true,true,window,"U+0009"); // tab
if(nowEle==inputs[inputs.length-1])nowEle=document; nowEle.focus && nowEle.focus(); nowEle.dispatchEvent(e);
1.document.createEvent
DOM3 新方法,創建事件,參考資料:淺談Javascript事件模擬。
2.e.initKeyboardEvent
設置事件參數,參考資料:WebKit 內核瀏覽器 initKeyboardEvent 函數原型。
3.nowEle.dispatchEvent(e)
指定事件對象。
收獲:
源自一個討論群里的小問題,有點感興趣就查了查,寫了個小demo,看來JavaScript里還有很多東西要去挖掘,前端大路漫漫。