使用键盘</select>时,<select>更改事件未触发

时间:2012-03-21 14:07:31

标签: jquery onchange

http://jsfiddle.net/rFEER/

<select id="users">
<option value="1">jack</option>
<option value="2">brill</option>
<option value="3">antony</option>
</select>​

JS:

$("#users").change(function(){
    alert($(this).val());
})​

为什么在单击鼠标之前使用(keyup / keydown)时更改事件未被触发

6 个答案:

答案 0 :(得分:29)

  

为什么在单击鼠标之前使用(keyup / keydown)时更改事件未被触发

焦点离开select时也会触发。这就是change事件的工作原理。

如果您需要主动通知,则必须关注changekeydown(至少,您可能需要click)并处理获取事件的情况值实际上没有改变,你必须处理这些事件中的一些事件(例如keydown)在更改值之前触发 ,所以你必须等待一会儿才能处理这个事件。或者请参阅使用keyup的{​​{3}} - 这将不那么主动(直到密钥发布才更新,这可能是可取的),但是您不需要延迟(setTimeout)我的代码有。

示例(SpYk3HH's answer):

HTML(我冒昧地改变了价值观,因此每个名字都更清晰了):

<select id="users">
<option value="j">jack</option>
<option value="b">brill</option>
<option value="a">antony</option>
</select>​

JavaScript的:

$("#users").bind("keydown change", function(){
    var box = $(this);
    setTimeout(function() {
        display(box.val());
    }, 0);
});

2016年注意:bind已基本上被live copy取代。在上面你只是将“bind”替换为“on”。

答案 1 :(得分:17)

尝试更改

$("#users").change(function(){

$("#users").bind('change keyup', function(e) {

应该为onchange事件和按下向上或向上箭头键绑定yyour函数

请注意,您也可以使用keydown,但它可能无法按预期执行,因为您的代码将在进行选择更改之前运行

如果你想要一个无限滚动选择框,我有一个漂亮的小函数我写到目前为止,至少对我来说,工作完美,可以自己分配所有,而不影响其他键盘操作,当然,并且考虑到我们的目的,这是在键盘上工作的,所以你仍然必须反复按箭头键,但它将继续循环所有选项。虽然,我很确定它也适用于keydown,但我们不这样使用它,所以我没有测试它。同样,keydown可能无法按预期执行,特别是如果select只有2或3个选项。

function selectInfinateScroll() {
    if ($(this).data("lastSelected")) {
        if ($(this).data("lastSelected")[0] == $(this).children("option:selected")[0]) {
            if ($(this).children("option:selected").index() == 0) {
                $(this).children("option:selected").prop("selected", false);
                $(this).children("option:last-child").prop("selected", true).change();
            }
            else {
                $(this).children("option:selected").prop("selected", false);
                $(this).children("option:first-child").prop("selected", true).change();
            };
        };
    };
    $(this).data("lastSelected", $(this).children("option:selected"));
}

$(function() {
    //  Enable 'Scrolling Through' on Select Boxes
    $("select").keyup(selectInfinateScroll);
});

已更新!


我将离开原始答案,因为它使用的替代方法可能对某些人更有用。但是,我已经提出了一个可以在“keydown”上运行的较短函数和一个使用所述函数的jQuery插件,该函数允许用户“按住”和箭头键并仍然无限地对选项进行排序!

首先,新功能

function keydownInfiniteSelect(e) {
    var eKey = e.which || e.key,
        selected = $(this).find("option:selected");
    if (eKey == 38 && selected.is(":first-child")) {    //    up arro
        $(this).find("option").last().prop("selected", true);    //    set value to last option
        $(this).change();    //    ensure select triggers change do to return false
        return false;    //    keeps select from skipping to second last option
    }
    else if (eKey == 40 && selected.is(":last-child")) {    //    down arro
        $(this).val($(this).find("option").first().val());    //    set value to first option
        $(this).change();    //    ensure select triggers change
        return false;    //    keeps select from skipping to second option
    }
}

使用方式:$("select").keydown(keydownInfiniteSelect);

和jQuery插件样式!

(function($){$.infiniteSelect||($.extend({infiniteSelect:function(b){return b.each(function(){$(this).data("infiniteSelect")||($.fn.on?$(this).on("keydown",$.infiniteSelect.methods.keydownInfiniteSelect).data("infiniteSelect",!0):$(this).bind("keydown",$.infiniteSelect.methods.keydownInfiniteSelect).data("infiniteSelect",!0))})}}),$.fn.extend({infiniteSelect:function(){return $.infiniteSelect($(this))}}),$.infiniteSelect.methods={keydownInfiniteSelect:function(b){b=b.which||b.key;var c=$(this).find("option:selected");
if(38==b&&c.is(":first-child"))return $(this).find("option").last().prop("selected",!0),$(this).change(),!1;if(40==b&&c.is(":last-child"))return $(this).val($(this).find("option").first().val()),$(this).change(),!1}})})(jQuery);

用作$("select").infiniteSelect() $.infiniteSelect("select")

jsFiddle of Plugin Minified

Uncut Plugin Fiddle

PS。我几乎已经为函数准备了一个Vanilla JavaScript,除了该方法的“set to last option”部分保持死亡,或者为null,或者跳到倒数第二个。我似乎无法正确设置它。如果有人想要修复并更新,我会非常感激。见HERE

答案 2 :(得分:5)

这是正常行为......

引用w3c specs

  

更改
      当控件失去输入焦点并且自获得焦点后其值已被修改时,会发生更改事件。此事件对INPUT,SELECT和TEXTAREA有效。元件。

答案 3 :(得分:1)

使用上面的答案,我能够得到我需要的行为:

$( "select" ).bind('keyup', function(e) {
    $(  '#' + e.target.id ).trigger('change');
});

答案 4 :(得分:-1)

$("#users").bind('change keyup', function(e) {

够了

答案 5 :(得分:-1)

/*After having been searching for hours i wrote my own. */



<script>
jQuery(document).ready(function () {
        /*********** SELECT PLZ ****************/
        /*********** SELECT PLZ ****************/
        /*********** SELECT PLZ ****************/
        jQuery('.dropedZip').html('' +
        '<select name="theName" id="theID" size="4" style="width: 184px" >' +
        '<option value="A">Choice A</option>' +
        '<option value="B">Choice B</option>' +
        '<option value="C">Choice C</option>' +
        '<option value="D">Choice D</option>' +
        '</select>');

        var nextOptValue = 0;
        var prevOptValue = 0;

        jQuery('#prop').keydown(function (e) {

            var key = e.which;
            if(key==13){
                var currOptValue = jQuery('select#theID > option:selected').val();// CURRENT
                alert('ausgesucht: '+currOptValue);
            }
            /* UP */
            if(key==38){
                var currOptValue = jQuery('select#theID > option:selected').val();// CURRENT
                if(currOptValue!=undefined){// CURRENT != undefined ?
                    prevOptValue = jQuery('select#theID > option:selected').prev('option').val();// PREV
                    if(prevOptValue!=undefined){// PREV != undefined ?
                        jQuery('select#theID > option:selected').removeAttr('selected');// REMOVE CURRENT
                        jQuery('select#theID > option[value='+prevOptValue+']').prop('selected',true);// SET PREV
                        jQuery('input#prop').val(prevOptValue);// SET INPUT VALUE : OTHER
                    }
                }
            }
            /* DOWN */
            if(key==40){
                if(jQuery('select#theID > option:selected').val()==undefined){// NULL
                    nextOptValue = jQuery('select#theID > option:first').val();// FIRST
                    jQuery('select#theID > option[value='+nextOptValue+']').prop('selected',true);// SET FIRST
                    jQuery('input#prop').val(nextOptValue);// SET INPUT VALUE : FIRST
                }else{
                    nextOptValue = jQuery('select#theID > option:selected').next('option').val();// NEXT
                    jQuery('select#theID > option:selected').removeAttr('selected');// REMOVE FIRST
                    jQuery('select#theID > option[value='+nextOptValue+']').prop('selected',true);// SET NEXT
                    jQuery('input#prop').val(nextOptValue);// SET INPUT VALUE : OTHER
                }

            }

        });
        /*********** SELECT PLZ ****************/
        /*********** SELECT PLZ ****************/
        /*********** SELECT PLZ ****************/


    });
</script>

        <input id="prop" type="text">
<div class="dropedZip"></div>