2012-04-01 138 views
1

我有一段JavaScript为我构建了一些HTML,并将它插入div。我正在使用jQuery 1.7.2进行此测试。如何正确捕获动态插入的“输入”文本元素的onchange或onkeyup事件?

我有兴趣在名为gene_autocomplete_fieldinput文本字段上附加自定义更改或键盘事件处理程序。

这是我到目前为止尝试过的。

下面的函数构建HTML,这是插入div称为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)); 

在我的呼唤HTML,我抓住从gene_container元素gene_autocomplete_field,然后我重写了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()函数J乌斯季发出警报:

function refreshGenePicker(val) { 
    alert(val); 
} 

结果

如果我输入任何字母到gene_autocomplete_field元素,事件处理似乎需要alert(val)的无数次。我收到了一个接一个的警报,浏览器被对话框接管。返回的值是正确的,但我担心refreshGenePicker()一遍又一遍地被调用。这不是正确的行为,我不认为。

问题

  • 如何正确采集keyup事件一次,所以我只处理内容的变化来自动完成视野中的一个时间?
  • 我应该为此使用不同的事件吗?

UPDATE

事实证明,不仅仅是一个keyCode 13(Return/Enter键)可以是一个问题 - 按下Control,Alt键,Esc键或其它特殊字符将触发事件(但就无限循环问题而言,将是无症状的)。我筛选的基因名称中没有元字符。所以我做了使用alphanumeric detection test的滤除进一步处理事件,其中包括返回键非字母数字字符:

if (!alphaNumericCheck(event.keyCode)) return; 
+0

看来.live被贬损赞成.on http://api.jquery.com/live/ – 2012-04-01 13:17:33

+0

你介意发布[小提琴](http://jsfiddle.net) – 2012-04-01 13:19:34

回答

5

alert被称为无限次。改为使用.on('change')。当您在alert中使用输入时,这将防止refreshGenePicker被调用。

然而,如果输入元件失去聚焦'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()); 
}); 

这将过滤任何进入的进入KEYUP事件(jsFiddle demo)。也切换到.on并删除.live

编辑:请注意,有更多的可能性,否认了alert模式,如escapespace关键。你应该在你的refreshGenePicker里面加一个支票,实际上的值是否变为

+0

谢谢,在'event.keyCode'上测试了! – 2012-04-01 13:31:02

+0

嗯在什么浏览器是文本字段返回捕获?无法在Chrome上重现。 – PeeHaa 2012-04-01 13:32:13

+0

我正在测试Safari 5.1.5和Chrome 18.0.1025.142。 – 2012-04-01 13:33:07

1

,如果你使用jQuery> 1.7你真的应该使用.on()

结账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);​ 
-1
$(document).ready(function() { 
    $('#test').html('<input id="text" />'); 
    $('#text').keyup(function() { 
     console.log($(this).val()); 
    }); 
});​ 

这一切正常。既然你已经有了<script>标签中的第二个代码块,你可能会多次运行它 - 这会导致它不止一次绑定,并且每次绑定都会产生多个警报。在添加密钥之前,您当然可以在该输入上使用.unbind(),但我认为更好的解决方案是将所有代码分组在一个$(document).ready();中,以确保您只绑定一次对象。因为你使用“Enter”键确认/解除警报

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

+0

不,这不在动态插入的HTML上工作。这只会在'input'元素已经存在时才起作用。 – 2012-04-01 13:24:07

+0

看到我的更新... – 2012-04-01 13:26:22

相关问题