簡體   English   中英

按住“ enter”鍵時如何防止觸發按鈕事件?

[英]How to prevent triggering button event when press 'enter' key and hold?

案例展示一擊:

如果單擊按鈕,然后按住“ Enter”鍵不放,則按鈕的單擊事件將不斷觸發。

 document.querySelector('button').addEventListener('click', function (e) { console.log(1); }) 
 <button>press Enter</button> 

沒有jQuery,沒有表單,沒有輸入。 我想知道這是如何工作的以及如何預防...

謝謝你。

發生這種情況的原因是,按下按鈕上的Enter會觸發其單擊事件,並且當您按住某個鍵時,會重復出現重復鍵並不斷重復“鍵入”該鍵。

如果要在觸發一次事件后一段時間忽略事件,可以將代碼添加到處理程序中以執行以下操作:

 var IGNORE_TIME = 1000; // One second var lastClick = null; document.querySelector('button').addEventListener('click', function (e) { var now = Date.now(); if (!lastClick || now - lastClick > IGNORE_TIME) { lastClick = now; console.log(1); } }); 
 <button>press Enter</button> 

如果你不想在按下回車鍵按鈕“點擊”它(我不推薦,你可能很難有人與誰依賴於使用鍵盤殘疾),可以防止keydown上的按鈕事件:

 document.querySelector('button').addEventListener('click', function (e) { console.log(1); }); document.querySelector('button').addEventListener('keydown', function (e) { var key = e.keyCode || e.charCode; if (key == 13) { e.stopPropagation(); e.preventDefault(); } }); 
 <button>press Enter</button> 

另請參見vlaz的answer ,它僅在按鍵重復時才阻止按鍵,這似乎是一個很好的折衷方案。

這是由於單擊按鈕時的事實。 按鈕保持焦點狀態

修改后的答案:按住某個鍵時,您希望獲得的事件順序為keydown > keypress > keydown > keypress ->(...重復兩次相同的事件...)-> keyup 知道了這一點,您可以跟蹤在keydown中按下的內容,並知道它最終在keyup結束了。

 document.querySelector('button').addEventListener('click', function (e) { console.log(1); }); var keysCurrentlyPressed = {}; document.querySelector('button').addEventListener('keydown', function (e) { var key = e.keyCode || e.charCode; if (keysCurrentlyPressed[key]) { e.stopPropagation(); e.preventDefault(); } else { //this is the first time the key is pressed, add an entry for this key keysCurrentlyPressed[key] = true; } }); document.querySelector('button').addEventListener('keyup', function (e) { var key = e.keyCode || e.charCode; delete keysCurrentlyPressed[key]; //note that the key isn't pressed any more }); 
 <button>press Enter</button> 

這將適用於所有符合DOM Level 3的環境,因此適用於所有主流瀏覽器。 但是, 根據MDN,某些較舊的環境會將按下的鍵視為重復按下該鍵,每次發送keydown > keypress > keyup 如果是這樣,您可以使用TJ Crowder的解決方案,該解決方案使用超時期限

如果使用ES6,則可以將按下的鍵存儲在Set中,並且可以將整個內容包裝在一個封閉的容器中,以防止這些鍵可用於可能不需要它們的其他代碼。

 document.querySelector('button').addEventListener('click', function (e) { console.log(1); }); (function() { const keysCurrentlyPressed = new Set(); document.querySelector('button').addEventListener('keydown', e => { const key = e.keyCode || e.charCode; if (keysCurrentlyPressed.has(key)) { e.stopPropagation(); e.preventDefault(); } else { keysCurrentlyPressed.add(key); } }); document.querySelector('button').addEventListener('keyup', e => keysCurrentlyPressed.delete(e.keyCode || e.charCode)); })() 
 <button>press Enter</button> 

原始答案:通過查看Event.repeat屬性,可以防止按住某個鍵。 但是,Edge或Internet Explorer不支持repeat屬性,因此僅在Chrome,Firefox和Safari上有效。

 document.querySelector('button').addEventListener('click', function (e) { console.log(1); }); document.querySelector('button').addEventListener('keydown', function (e) { if (e.repeat) { //don't do anything if a key is held down. e.stopPropagation(); e.preventDefault(); } }); 
 <button>press Enter</button> 

如果您按一下按鈕並按住Enter鍵或空格鍵,則不會發生重復事件。

值得注意的是-您需要為鍵盤事件( keydownkeypresskeyup )添加一個偵聽器,以使用repeat屬性。 click是鼠標事件,沒有repeat ,因為它沒有意義。

由於按鈕具有焦點,因此將每個事件(按Enter鍵)定向到該按鈕並執行。 為了防止它發生多次,可以使用blur()刪除焦點。 然后,它僅執行一次,直到用戶再次將焦點設置在按鈕上。

document.querySelector('button').addEventListener('click', 
  function (e) {
    console.log(1);
    this.blur();
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM