2012-12-25 13 views
4

使用Javascript/jQuery,當某人按下某個鍵時,如何自動重複keydown事件或等效事件?當按鍵被按下時,跨瀏覽器的方式來自動重複keydown事件

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

在我的情況下,該解決方案會遇到問題。我正在設計一個在線實驗。用戶應該按住整個實驗的「T」鍵,永不放棄。該實驗由多次試驗組成,每次試驗都無法獲得以前試驗記錄的信息。因此,試驗1可以記錄T的keydown,但試驗2不能訪問該記錄,因此不知道T是否已經關閉。

現在,如果按住T鍵會產生T的自動重複keydown事件,我不會有任何問題,因爲試驗2只會捕獲T來的下一個keydown事件。但它看起來像我不會得到自動重複keydown事件從按住按鍵,至少在Firefox中。從我所看到的情況看,不同瀏覽器處理關鍵字的方式有所不同。什麼是解決我的問題的良好的跨瀏覽器方式?順便說一句,如果它很重要,我還需要能夠檢測其他鍵的鍵盤事件和鍵盤事件,同時進行所有這些操作。

編輯:在閱讀了我回來的一些評論並證實我確實在普通情況下得到了重複的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> 

如果你按一個鍵,並按住不放,然後鬆開,然後再按,該行爲符合市場預期,即有一個計數器,它鍵被按下時遞增,釋放時消失,然後再次按下時開始遞增。但如果你按下兩個鍵,然後釋放ONE,我會認爲另一個(未釋放)鍵將繼續發送keydown事件,以便計數器(在重置後)繼續增加。事實上,這並沒有發生。任何想法爲什麼以及如何使它發生?

+0

我沒有測試過其他環境中,但在Chrome在Mac上運行雪豹,當由於自動重複,我按住了一個鍵,重複發生了keydown事件。 – Barmar

+0

感謝你的回覆,看起來你一般都是對的 - 在特定的情況下,我只是沒有得到重複的關注。我在我原來的帖子中澄清了這些。 – baixiwei

回答

6

在我試過的瀏覽器中,當按住可鍵入的按鍵時,我重複了按鍵事件。我不知道這是否是您實際需要解決的問題。

但是,如果你確實認爲你需要解決,或者如果你想自己控制的重複率,你可以做這樣的:

  1. 捕獲的KeyDown和KEYUP的事件。
  2. 在keydown上,設置一個間隔計時器,但通常會觸發,但您想知道密鑰仍然處於關閉狀態。
  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; 
    } 
}); 

如果你想自動重複的關鍵永遠,直到它被提升,即使被壓在此期間發佈的其他按鍵,你想那些其他鍵做自己的自動重複,然後操作系統不ipmlement的行爲,所以你必須自己實現它。你可以做這樣的事情,並將每個鍵重複事件調用回調函數:

工作演示: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函數被調用所有這些製造自動重複事件,並通過了關鍵這是自動重複。

+0

感謝您的回覆!我可能誤解了這個問題。看起來我在一般情況下會重複發生關鍵事件。但我(我想)在我所需要的特定環境下不會得到它們。我將更多細節添加到我原來的帖子中。 – baixiwei

+0

只是爲了防止我在原始文章中的澄清不明顯 - 建議的解決方案不會(我認爲)在我的情況下工作,因爲我需要解除綁定我的keyup和keydown函數,然後重新綁定它們。顯然這樣做會「打破」重複的關鍵時間或類似的東西? – baixiwei

+0

@baixiwei - 我的方法可以檢測特定按鍵的向下/向上和使用自己的計時器來生成重複事件,這使您可以有足夠的控制來解決您的問題。如果你正在尋找一個特定的密鑰,那麼你只需要編碼來監視它,忽略其他密鑰。 – jfriend00

0

看看這個jQuery插件:fastKeys我想,這是你想要/需要什麼...

相關問題