在我的网站上,我有一个输入字段,用户可以在其中输入用户名以将协作者添加到项目中。当用户开始输入用户名(使用AJAX)时,我会动态创建下拉列表,以便从数据库中获取可能已注册的用户名:
上述下拉列表的HTML是:
<div class="search_results">
<div class="dropdown open">
<a class="search_results_toggle" data-toggle="dropdown" href="#"></a>
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
<li class="tiff"><a class="search_result" href="#">tiff</a></li>
<li class="ttseng"><a class="search_result" href="#">ttseng</a></li>
</ul>
</div>
</div>
我认为通过以下方式找出列表中的哪个元素是直截了当的:
$(document).ready(function(){
$('.search_result').click(function(){
console.log('clicked search result');
// replace the form with the username
$(this).closest('form').remove();
$(this).closest('.user').append($(this).html());
});
});
但是,我发现使用动态创建的列表元素,我无法成功获取任何事件(不会创建控制台消息)。我发现唯一有效的方法是检测用户何时悬停在$('。dropdown')div上,但如果我尝试检测点击/悬停在其任何子元素上(例如下拉菜单,li,a)等),它不起作用,我需要找到所选择的确切元素。
这是使用动态创建的Jquery下拉列表的已知问题吗?我该如何解决这个问题?
答案 0 :(得分:3)
对于动态创建的元素,请使用on方法
$(document.body).on('click', '.search_result' ,function(){
答案 1 :(得分:2)
这实际上是您的点击监听器的问题。
以下是发生的事情:
$('.search_result')
(大致)是与此CSS选择器匹配的HTML元素数组。
执行$('.search_result').click(whatever)
会在创建创建时选择匹配此选择器的元素时调用click
。
因此,如果您稍后创建元素,它们将永远不会附加某些内容。
您要做的是使用on
的后代选择器。
$('.search_results').on('click','.search_result',whatever)
在这种情况下会发生的事情是只有一个事件监听器(在整个.search_results
div上)。当触发click
事件时,jQuery会检查后代search_result
(第二个字符串)是否能够捕获事件。这甚至在添加新的搜索结果时也会起作用:毕竟,click事件在容器上,所以只要容器存在,就会存在这个事件监听器。
实际上,即使在静态情况下,最好使用第二种形式:在第一种形式中,您将创建n
个事件监听器(每个搜索结果为1),第二种形式为仅创建1。 / p>
答案 2 :(得分:0)
您的代码在加载文档时将事件侦听器附加到已知的.search_result元素,您需要做的是在创建新元素时附加侦听器。
你碰巧在哪里调用$('。dropdown-menu')。append()是你需要添加监听器的地方。
var li = $('<li>test</li>');
li.on('click', function(){
alert('I was clicked.');
});
$('ul').append(li);
简单示例 - http://jsfiddle.net/4FPx5/