簡體   English   中英

跨瀏覽器的方式,在按住鍵時自動重復重復按下事件

[英]Cross-browser way to get automatically repeating keydown events when key is held down

使用Javascript / jQuery,當有人按住某個鍵時,如何自動重復按下鍵事件或等效操作?

我真正想要的是能夠檢查某個鍵是否按下,但是從這里的其他問題來看,這似乎是不可能的。 建議的解決方法似乎是記錄keydown和keyup事件,然后如果已記錄keydown事件並且沒有后續的keyup,則假定該鍵已關閉。

在我看來,該解決方案遇到了問題。 我正在設計一個在線實驗。 用戶應在整個實驗過程中按住“ T”鍵,不要松開。 該實驗包含多個試驗,每個試驗都無法訪問先前試驗記錄的信息。 因此,試驗1可以記錄T的密鑰按下,但是試驗2無法訪問該記錄,因此不知道T是否被按下。

現在,如果按住T鍵會自動為T產生重復的按鍵事件,那么我將沒有問題,因為試驗2只會捕獲下一個按鍵事件以使T出現。 但是,看來至少在Firefox中,我不會通過按住鍵來自動重復按鍵事件。 從我所看到的情況來看,不同的瀏覽器處理按下鍵的方式似乎有所不同。 什么是跨瀏覽器解決我的問題的好方法?

順便說一句,如果這很重要,那么在進行所有這些操作的同時,我還需要能夠檢測其他鍵的keyup和keydown事件。

編輯:閱讀了一些評論后,我回過頭來驗證我確實確實在通常情況下會重復發生鍵盤按下事件。 但是我真的沒有在需要它們的特定情況下使用它們。 我有一些簡單的代碼,我認為可以解決這個問題:

<!DOCTYPE html>
<html>

<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
</head>

<body>
<div id="target"></div>
</body>

<script type="text/javascript">

var i;
function foo() {
    i++;
    $('#target').html(i);
}

function doTrial() { // do trial
    i=0;
    $(document).keydown(foo);
    $(document).keyup(endTrial);
}

function endTrial() { // end trial
    $('#target').html('');
    $(document).unbind('keydown',foo);
    $(document).unbind('keyup',endTrial);
    doTrial();
}

doTrial();

</script>

</html>

如果按下某個鍵並按住不放,然后松開,然后再次按下,則行為符合預期,即,有一個計數器,按住該鍵時該計數器增加,釋放該鍵時消失,然后按下該鍵再次開始增加計數再次。

但是,如果您按下兩個鍵,然后釋放一個,我會認為另一個(未釋放)鍵將繼續發送按鍵事件,以便計數器(在重置之后)繼續遞增。 實際上,這不會發生。 知道為什么以及如何實現它嗎?

在我嘗試使用的瀏覽器中,按住可鍵入的鍵時,重復出現了鍵按下事件。 我不知道這是否是您實際上需要解決的問題。

但是,如果您確實認為需要解決此問題,或者如果您想自己控制重復率,則可以執行以下操作:

  1. 捕獲事件以進行擊鍵和擊鍵。
  2. 按下按鍵時,設置一個間隔計時器,該計時器會觸發,但是您經常想知道按鍵仍在按下狀態。
  3. 在鍵入該鍵時,停止間隔計時器。
  4. 只要按住該鍵,您將以跨瀏覽器的方式反復收到通知。

此處的工作演示: http : //jsfiddle.net/jfriend00/XbZYs/

var downTimer;
var lastKey;
$(document.body).keydown(function(e) {
    // if not still the same key, stop the timer
    if (e.which !== lastKey) {
        if (downTimer) {
            clearInterval(downTimer);
            downTimer = null;
        }
    }
    // remember previous key
    lastKey = e.which;
    if (!downTimer) {
        // start timer
        downTimer = setInterval(function() {
            $("#result").append("+");
        }, 125);
    }
}).keyup(function(e) {
    // stop timer
    if (downTimer) {
        clearInterval(downTimer);
        downTimer = null;
        lastKey = 0;
    }
});

如果您希望某個鍵在彈出之前一直永久自動重復,即使同時按下並釋放了其他鍵,並且您希望這些其他鍵執行自己的自動重復操作,則操作系統也不會執行該操作,所以您將不得不自己實施。 您可以執行以下操作,為每個鍵重復事件調用一個回調函數:

工作演示: http : //jsfiddle.net/jfriend00/aD3Eg/

// this is called for every manufactured repeat event
// the frequency of the repeat event is determined by the time value set
// on setInterval() below
function repeatCallback(key) {
    $("#result").append(key + " ");
}

var repeatState = {};
$(document.body).keydown(function(e) {
    var key = e.which;
    // if no time yet for this key, then start one
    if (!repeatState[key]) {
        // make copy of key code because `e` gets reused
        // by other events in IE so it won't be preserved
        repeatState[key] = setInterval(function() {
            repeatCallback(key);
        }, 125);
    } else {
        // nothing really to do here
        // The key was pressed, but there is already a timer
        // firing for it
    }
}).keyup(function(e) {
    // if we have a timer for this key, then stop it 
    // and delete it from the repeatState object
    var key = e.which;
    var timer = repeatState[key];
    if (timer) {
        clearInterval(timer);
        delete repeatState[key];
    }
});
​

對所有這些制造的自動重復事件都調用repeatCallback函數,並傳遞了自動重復的密鑰。

看一下這個jQuery插件: fastKeys我認為,這就是您想要/需要的...

暫無
暫無

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

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