下拉列表中的keydown事件

Bry*_*yan 21 html javascript jquery google-chrome

我正在尝试创建一个下拉列表,当用户持有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.
    }
});
Run Code Online (Sandbox Code Playgroud)

仅当您在进入下拉列表之前按住Shift键时才有效.如果您在DDL内并按下shift键,则keyup/keydown事件将不会触发并shifted保持不变false

有没有办法在下拉列表聚焦时捕获keyup/keydown事件?

编辑:

看起来它可能只是Chrome的问题,只是尝试添加以下内容,它适用于Firefox和IE,但不适用于Chrome:

$(document).on('keyup keydown', 'select', function (e) {
    shifted = e.shiftKey;
});
Run Code Online (Sandbox Code Playgroud)

这是一个不适用于chrome的小提琴:http://jsfiddle.net/ue6xqm1q/4

Ric*_*ock 9

我认为@ judgeja的回应可能是你最好的选择.我将此作为"回答"而不是评论发布,因为我已经完成了自己的研究,以确定select在Chrome中打开元素时绝对不会触发任何事件.

见小提琴:http: //jsfiddle.net/m4tndtu4/6/

我已经将所有可能的事件处理程序(我认为)附加到input元素和两个select元素上.

在Chrome中,您会看到在处理input元素时会触发许多事件,但是当第一个select元素打开时,您将看到没有事件触发.

有趣的是,事件火在Chrome中,如果select元素具有multiple属性或size> 1.

在Firefox中,您将看到在所有三个元素上触发的事件.

在@ judgeja的建议之外,你最好的选择可能是模拟select元素.


Fra*_*oMM 6

UPDATE

警告:Chrome(mis)行为在不同平台上有所不同!在Chrome Windows中,keydown事件在select发布后立即触发,而在OsX上则不是.这解释了为什么@judgeja解决方案适用于某些人,而不适合我,而我的工作是在OsX而不是在Windows上工作.

所以我创建了一个更新的小提琴,将我的OsX解决方案与他的Windows解决方案合并.

http://jsfiddle.net/0fz5vcq6/5/

在触发keydown的平台上使用@judgeja解决方案,如果没有触发,它会测试没有先前keydown的keyup事件(我以前的解决方案).这很丑,因为它仅在Shift键的RELEASE之后才能工作,但仅在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);
    });
}
Run Code Online (Sandbox Code Playgroud)

积分主要归功于@judgeja的计时器解决方案,其中包括针对Mac(以及行为相同的其他平台)的一些补充解决方法

我仍然认为的东西HTML像模仿选择http://gregfranko.com/jquery.selectBoxIt.js/是清洁的,因为他们不应该的keydown/keyups干扰.

以前的解决方案(仅限OsX)

在完全没有任何事件的情况下,我能想到的唯一解决方案是测试是否在没有前一次下移的情况下发生了升档.如果您没有其他元素的行为与选择相同,则可能会有效

http://jsfiddle.net/6jkkgx5e/

它有点棘手和肮脏,在用户释放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;
    }
});
Run Code Online (Sandbox Code Playgroud)

应该在非bug的浏览器上正常运行.无论如何,我同意用http://gregfranko.com/jquery.selectBoxIt.js/这样的HTML来模拟选择可能是更清洁的方式.


MCS*_*arp 3

你的语法看起来不正确。

$("#target").keydown(function() {
    alert( "Handler for .keydown() called." );
});
Run Code Online (Sandbox Code Playgroud)