如何为动态插入的“input”文本元素正确捕获onchange或onkeyup事件?

时间:2012-04-01 13:11:46

标签: javascript jquery html events event-handling

我有一些JavaScript为我构建了一些HTML并将其插入div。我正在使用 jQuery 1.7.2 进行此测试。

我有兴趣在名为input的{​​{1}}文本字段上附加自定义更改或加密事件处理程序。

这是我到目前为止所尝试的内容。

以下函数构建HTML,将其插入名为gene_autocomplete_field的{​​{1}}中:

div

在我的调用HTML中,我从gene_container元素中抓取function buildGeneContainerHTML(count, arr) { var html = ""; // ... html += "<input type='text' size='20' value='' id='gene_autocomplete_field' name='gene_autocomplete_field' placeholder='Enter gene name...' /><br/>"; // ... return html; } // ... $('#gene_container').html( buildGeneContainerHTML(count, geneNameArr) ); ,然后覆盖gene_autocomplete_field的{​​{1}}事件处理程序:

gene_container

当我更改keyup中的文字时,gene_autocomplete_field功能只会发送提醒:

<script>
    $(document).ready(function() {
        $("#gene_container input:[name=gene_autocomplete_field]").live('keyup', function(event) {
            refreshGenePicker($("#gene_container input:[name=gene_autocomplete_field]").val());
        });
    });
</script>

结果

如果我在gene_autocomplete_field元素中键入任何字母,事件处理程序似乎无限次地调用refreshGenePicker()。我接着一个警报,浏览器被对话框接管。返回的值是正确的,但我担心function refreshGenePicker(val) { alert(val); } 被一遍又一遍地调用。这是不正确的行为,我不这么认为。

问题

  • 如何正确捕获gene_autocomplete_field事件一次,以便我只处理一次对自动填充字段的内容更改?
  • 我应该为此目的使用不同的事件吗?

更新

事实证明,不仅仅是alert(val)的13(返回/回车)可能是一个问题 - 按Control,Alt,Esc或其他特殊字符将触发事件(但到目前为止无症状)因为无限循环问题)。我过滤的基因名称中没有元字符。所以我使用alphanumeric detection test来过滤掉进一步事件处理中的非字母数字字符,其中包括Return键:

refreshGenePicker()

3 个答案:

答案 0 :(得分:5)

alert被称为无限次,因为您使用“Enter”键来确认/取消警报。请改用.on('change')。当您在refreshGenePicker中使用Enter时,这将阻止alert被调用。

但是,'change'事件只会在输入元素失去焦点时触发。如果您想在每个密钥上使用refreshGenePicker,请改用以下方法:

$("#gene_container input:[name=gene_autocomplete_field]").live('keyup', function(event) {
    if(event.keyCode === 13) // filter ENTER
        return;
    refreshGenePicker($("#gene_container input:[name=gene_autocomplete_field]").val());
});

这将过滤任何传入的输入密钥事件(jsFiddle demo)。同时切换到.on并放弃.live

编辑:请注意,有更多可能会解除alert模式,例如escapespace密钥。您应该在refreshGenePicker内添加一项检查,看看该值是否实际已更改

答案 1 :(得分:1)

如果你使用的是jQuery&gt;你应该真的使用.on() 1.7。

查看the perftest

并查看我的一些related question

同样,当测试相等时,您应该添加quotes around it

input:[name='gene_autocomplete_field']

回答你真正的问题:)。它不应该像你提供的代码那样表现。也许别的东西是错的。你可以设置一个jsfiddle问题吗?

查看my demo,也许您会看到代码出了什么问题:

function refreshGenePicker(value) {
    console.log('keyup! Value is now: ' + value);
}

(function($) {
    var someHtml = '<input type="text" name="gene_autocomplete_field">';
    $('body').append(someHtml);

    $('body').on('keyup', 'input[name="gene_autocomplete_field"]', function(e) {
        refreshGenePicker($(this).val());
    });
})(jQuery);​

答案 2 :(得分:-1)

$(document).ready(function() {
    $('#test').html('<input id="text" />');
    $('#text').keyup(function() {
        console.log($(this).val());
    });
});​

这很好用。由于您在<script>标记中有第二个代码块,因此您可能会多次运行它 - 这会导致它多次绑定并在每次绑定时生成多个警报。在添加密钥之前,您当然可以在该输入上使用.unbind(),但我认为更好的解决方案是将所有代码分组到一个$(document).ready();中,以确保您只绑定对象一次

http://jsfiddle.net/Ka7Ty/2/