我有一组输入,我想在当前显示的最后一个输入获得焦点时添加另一个输入。表单以2个输入开始。
$('.answer_fields input:last-child').focus(function(event) {
var nextfield = $('.answer_fields input').length + 1;
$('.answer_fields').append('<input class="form-control answer_field" placeholder="Answer option #' + nextfield +'" id="answer' + nextfield +'">');
});
目前的情况是,只有在第二个输入(原始的“最后一个孩子”)获得焦点时才会附加其他字段。
检查源似乎表明输入正按预期添加到DOM。我错过了什么?
答案 0 :(得分:3)
在运行代码以安装.focus()
事件处理程序时,将对ONE评估jQuery选择器。当事情发生变化时,它不会被现场调整。如果您想要这种类型的行为,可以切换到事件委托。
使用将被实时评估的事件委托的类似事件处理程序如下所示:
$(some common parent selector).on("focus", ".answer_fields input:last-child", function() {
// code here
});
工作演示:http://jsfiddle.net/jfriend00/ZZLPJ/
首先,您的原始代码无效,因为您将事件处理程序附加到运行第一个代码时存在的特定元素。您将事件处理程序附加到哪些事件并未随着您的结构在未来发生更改而发生更改,因此新元素将不会包含事件处理程序,并且不会重新评估选择器的:last-child
部分。
事件委托是有效的,因为在给定元素上发生的某些事件将通过每个父元素冒出DOM层次结构。您可以将单个事件处理程序附加到公共父级,并且当该父级被通知发生给定事件时,它可以动态地评估您指定的选择器与发起该事件的子项目,如果它匹配,解雇您的事件处理程序这样就可以实现&#34;实时&#34;您想要的选择器评估。
为了给你一个想法,这些就是我所说的&#34;静态&#34;事件处理程序:
$(".test:last-child").focus(fn);
$(".test:last-child").on("focus", fn);
这是一个委托(以及动态)事件处理程序:
$("#parent").on("focus", ".test:last-child", fn);
有关此主题的更多信息,请参阅以下其他答案:
jQuery .live() vs .on() method for adding a click event after loading dynamic html
Does jQuery.on() work for elements that are added after the event handler is created?
Should all jquery events be bound to $(document)?
只是检查确定并且焦点事件确实会使用冒泡事件委派。
答案 1 :(得分:1)
这是人们开始使用jQuery的常见问题。事实证明,在首次加载页面时,命名的eventListeners(即$.fn.click
,$.fn.focus
等)会将事件侦听器附加到每个匹配的DOM元素。这些侦听器在匹配元素本身上定义 ,这意味着每个侦听器对于它所附加的元素是唯一的。
与通常所说的事件委派相比,您将听到此方法。事件委派涉及将偶然侦听器附加到共享父元素,该元素将检查event.target
属性以查看它是否符合您的标准(在您的情况下为.answer_fields input:last-child
)。这与将唯一侦听器附加到您希望定位的每个DOM元素不同,因为它允许您动态地向DOM添加新节点,然后由父节点的侦听器像任何其他节点一样处理。
要使用jQuery完成事件委派,请在共同祖先上使用.on()
函数(我以document
为例)并监听所有匹配元素作为第二个参数函数调用:
$(document).on('focus', '.answer_fields input:last-child', function(event) {
// your code here
});
这不仅可以解决动态创建的DOM元素的问题,而且事件委派还可以通过减少附加到DOM中元素的事件侦听器总数来大大提高页面的性能。
有关活动授权的详情,我们建议您查看此tutorial和此SO question