[英]keydown event in drop down list
我正在嘗試創建一個下拉列表,當用戶按住SHIFT鍵時,它將在所有其他下拉列表上選擇相同的索引。
目前,我正在執行以下操作:
$(document).on('keyup keydown', function (e) { shifted = e.shiftKey });
$(document).on('change', '.report_info select', function (e) {
if (shifted) {
//Code to change other drop down lists.
}
});
僅當您在輸入下拉列表之前按住Shift鍵時才有效。 如果您在DDL中並按Shift鍵,則不會觸發keyup / keydown事件,並且shifted
仍為false
在以下拉列表為重點時,有什么方法可以捕獲keyup / keydown事件?
編輯:
看來這可能僅是Chrome的問題,只需嘗試添加以下內容,即可在Firefox和IE中使用,但不能在Chrome中使用:
$(document).on('keyup keydown', 'select', function (e) {
shifted = e.shiftKey;
});
這是它在chrome中無法使用的小提琴: http : //jsfiddle.net/ue6xqm1q/4
我認為@judgeja的回復可能是您最好的選擇。 我將其發布為“答案”而不是評論,因為我已經進行了自己的研究,以確定當在Chrome中打開select
元素時,絕對不會觸發任何事件。
請參閱小提琴: http : //jsfiddle.net/m4tndtu4/6/
我已經將所有可能的事件處理程序(我認為)都附加到input
元素和兩個select
元素上。
在Chrome中,當您使用input
元素時,您會看到許多事件觸發,但是當第一個select
元素打開時,您將看不到任何事件觸發。
有趣的是,如果select
元素的multiple
屬性或size
大於1,則事件會在Chrome中觸發。
在Firefox中,您會看到所有三個元素均觸發事件。
除了@judgeja的建議之外,您最好的選擇可能是模擬select
元素。
更新
警告:Chrome(錯誤)行為在不同平台上有所不同! 在Chrome Windows中,釋放選擇后立即觸發了keydown事件,而在OsX上則不觸發。 這解釋了為什么@judgeja解決方案對某些人有用,而對我不起作用,而我的解決方案在OsX而非Windows上有效。
因此,我創建了一個更新的提琴,將我的OsX解決方案與他的Windows解決方案合並。
http://jsfiddle.net/0fz5vcq6/5/
在觸發了按鍵按下的平台上,使用@judgeja解決方案,如果未觸發,則會在沒有先前按鍵按下的情況下測試按鍵事件(我先前的解決方案)。 這很丑陋,因為只有在松開Shift鍵后才能工作,但僅在Chrome OsX上丑陋。
var shifted = false;
var hackytimer = 0;
var lastval=null;
$(document).keydown(function(e){
if(e.which == 16){
if(Date.now() - hackytimer <200){
alert("you pressed shift inside the select (Win)");
changeAllSelects($(this).val());
} shifted = true;
}
});
$(document).keyup(function(e){
if(e.which == 16) {
if(!shifted && lastval!=null) {
alert("you pressed shift inside the select (OsX)");
$('.report_info select').each(function () {
changeAllSelects(lastval);
});
}
shifted = false;
}
});
$(document).on('change', '.report_info select', function (e) {
hackytimer = Date.now();
if (shifted) {
changeAllSelects($(this).val());
} else {
lastval=$(this).val();
}
});
function changeAllSelects(cr){
hackytimer = 0;
$('.report_info select').each(function () {
$(this).val(cr);
});
}
Credit主要歸功於@judgeja的計時器解決方案,並為Mac(以及其他行為相同的平台)增加了一些解決方法
我仍然認為使用類似http://gregfranko.com/jquery.selectBoxIt.js/的 HTML來模擬選擇更為干凈,因為它們不應干擾keydown / keyups。
上一個解決方案(僅OsX)
在完全不發生任何事件的情況下,我能想到的唯一解決方案是測試是否發生了升檔而沒有先前的降檔。 如果您沒有其他元素的行為與選擇的行為相同,這可能會起作用
這有點棘手和骯臟,將在用戶釋放Shift鍵后起作用
var shifted = false;
var lastval=null;
$(document).keydown(function(e){
if(e.which == 16){
shifted = true;
}
});
$(document).keyup(function(e){
if(e.which == 16){
if(!shifted && lastval!=null) {
alert("you pressed shift inside the select");
$('.report_info select').each(function () {
$(this).val(lastval);
});
}
shifted = false;
}
});
$(document).on('change', '.report_info select', function (e) {
var cr = $(this).val();
if (shifted) {
$('.report_info select').each(function () {
$(this).val(cr);
});
} else {
lastval=cr;
}
});
在沒有錯誤的瀏覽器上應該可以正常運行。 無論如何,我同意使用類似http://gregfranko.com/jquery.selectBoxIt.js/的 HTML來模擬選擇內容,這可能是更干凈的方法。
您的語法看起來不正確。
$("#target").keydown(function() {
alert( "Handler for .keydown() called." );
});
老實說,這是一個非常棘手的解決方案,但這是達到目的的一種手段,直到您希望找到更好的東西。
由於問題是chrome在下拉列表消失之后才在select
元素上注冊keydown / keyup事件,因此我們需要
a)弄清楚如何使事件觸發(我不知道)
要么
b)檢查是否以其他順序滿足了我們的條件。
Chrome會在單擊后觸發shift鍵按下事件,因此我們可以簡單地檢查在此事件之前是否按下了click。 由於其他瀏覽器的行為更符合我們的預期,因此我們還將保留之前的代碼。
為此,我們在click事件上設置了一個計時器,然后在觸發select的shift事件時,如果還設置了click事件計時器,我們應該在此處運行代碼,以便chrome觸發它。 然后,我們重置計時器,以使其不會多次觸發。
注意 :如果您在設置值后立即按shift鍵(在指定的單擊限制之內),它也會全部設置。 我不認為這是不合理的,因為它在發生時實際上感覺很自然。
我使用以下代碼:
var shifted = false;
var hackytimer = 0;
$(document).on('keyup keydown', function (e) {
shifted = e.shiftKey;
});
$(document).on('keyup keydown', 'select', function (e) {
shifted = e.shiftKey;
if(Date.now() - hackytimer <200){
changeAllSelects($(this).val());
}
});
$(document).on('change', '.report_info select', function (e) {
hackytimer = Date.now();
if (shifted) {
changeAllSelects($(this).val());
}
});
function changeAllSelects(cr){
hackytimer = 0;
$('.report_info select').each(function () {
$(this).val(cr);
});
}
在這里查看工作示例: http : //jsfiddle.net/0fz5vcq6/2/
首先。 您應該選擇一個事件進行注冊。 不要同時注冊按鍵和按鍵。 您會給瀏覽器帶來困難,因為它們會影響您的最終結果。 要了解我的意思,只需編輯插件,添加一個keyup事件。 最終結果表現得有些草率。
keyup :釋放鍵盤上的鍵時觸發的事件。
keydown :按下鍵盤上的某個鍵時觸發的事件。
keypress :按下鍵盤上的某個鍵時觸發的事件。
他們有區別,最好堅持一個,在這個例子中我更喜歡使用keydown,只要和我玩得更好,就可以使用keyup。
編輯 :快速筆記。 我的示例的鍵盤輸入效果不佳,因為看來,selectedIndex中的更改首先出現,然后是綁定事件。 在按下keydown時,首先觸發事件,該事件是否起作用,然后selectedIndex更改。 要使用keyup,下面的代碼需要進行一些修改,這意味着在使用keyup時不需要此步驟。
我在這里有一個plnkr演示。
我已經在IE10,Opera,Safari,Firefox和Chrome上對其進行了測試。 如您所料,webkit瀏覽器不會在選擇列表具有焦點時觸發keydown / keyup / keypress事件。 目前尚不知道我的原因。 在Firefox中效果很好。 在IE上部分運作。 因此,為了實現您的目標,請自定義代碼進行救援! 我只是將更改事件綁定到文檔,我聽說了kewdown和更改。 如果事件類型已更改,則解決方法將發揮作用。 這里有一些代碼:
$(document).ready(function(){
$(document).on('keydown change', 'select', function(evt){
var shiftKey = evt.shiftKey;
var code = evt.keyCode || evt.which;
//if it's a change event and i dont have any shiftKey or code
//set the to a default value of true
if(evt.type === 'change' && !shiftKey && !code){
//special! only when change is fired
shiftKey = true;
code = true;
}
//if shift key
if(shiftKey && (code === 40 || code === 38 || code === true)){
var target = $(evt.target);
//if code is not true means it is not a change event, go ahead and set
//a step value, else no step value
var step = (code !== true) ? (code === 40) ? 1 : -1 : 0;
var index = target[0].selectedIndex + step;
//just to keep the lower and upper bound of the select list
if(index < 0){
index = 0;
}else if(index >= target[0].length){
index = target[0].length - 1;
}
//get all other select lists
var allOtherSelects = target.closest('div').siblings('div').children('select');
//foreach select list, set its selectedIndex
$.each(allOtherSelects, function(i, el){
el.selectedIndex = index;
});
}
});
});
Chrome hack:您可以為文檔設置自定義事件。 並在DDL中按Shift鍵時觸發此事件。 jQuery觸發觸發器可以傳遞自定義參數。
檢查工作的JS FIDDLER
針對您的情況嘗試以下腳本
<script type="text/javascript" language="javascript">
window.shifted = false;
$(document).on('keyup keydown', function (e) { shifted = e.shiftKey; });
$(document).on('change', 'select.report_info', function (e) {
var cr = $(this).val();
if (shifted) {
$('.report_info').each(function () {
$(this).val(cr);
});
}
});
</script>
布萊恩(Bryan),您可以嘗試以下方式進行操作。 我在Jsfiddle上進行了測試,如果我正確地提出了問題,它會以您的方式工作。
var shifted = false;
$(document).on('keyup keydown', function (e) { shifted = e.shiftKey; });
$("select").on('keyup keydown', function (e) {
shifted = e.shiftKey;
});
$('.report_info select').on('change', function (e) {
var cr = $(this).val();
if (shifted) {
$('.report_info select').each(function () {
$(this).val(cr);
});
}
});
請讓我知道它是否適合您。
跳這個東西幫你.. :)
var onkeydown = (function (ev) {
var key;
var isShift;
if (window.event) {
key = window.event.keyCode;
isShift = window.event.shiftKey ? true : false;
} else {
key = ev.which;
isShift = ev.shiftKey ? true : false;
}
if ( isShift ) {
switch (key) {
case 16: // ignore shift key
break;
default:
alert(key);
// do stuff here?
break;
}
}
});
我發現了一個專門針對Chrome的非常獨特的解決方案。 當選擇元素具有焦點時,Chrome似乎會偏離正常的dom,因此您永遠不會發生onkey(down | press | up)事件來捕獲鍵碼。 但是,如果選擇框的大小大於1,則可以使用。 但是任何想要實際下拉框而不是組合框的人都可以使用此代碼解決此問題。 就我而言,我試圖防止退格鍵退回到上一個瀏覽器頁面。
JavaScript看起來像這樣:
$(document).ready(function() {
$('select').keypress(function(event)
{ return cancelBackspace(event) });
$('select').keydown(function(event)
{ return cancelBackspace(event) });
});
function cancelBackspace(event) {
if (event.keyCode == 8) {
return false;
}
}
然后HTML看起來像這樣:
<select id="coaacct" style="border:none;width:295px;" onclick="if (this.size){this.size=''}else{this.size='20'};">
我使用onclick事件將沒有大小的選擇框的大小更改為20,如果有大小,則將其更改為空。 這樣,它的功能類似於普通的選擇下拉列表,但因為當您選擇選項時它的大小大於1,它將檢測到鍵碼。 我在其他任何地方都看不到這個答案,因此我想我會分享我的解決方案。
如果您需要使用如此細小的下拉列表來做事,那么按原樣使用本機<select>
元素可能不值得。 僅在此線程中,就討論了許多實現上的差異,並且有許多其他內容不在本討論的范圍之內,但也可能會影響您。 有幾個JS庫可以包裝此控件,將其保留在移動設備上(實際上需要本機控件),而在桌面上進行仿真,而該控件實際上並沒有做很多在JS中無法仿真的事情。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.