如何将javascript事件处理程序附加到在javascript中创建的这些元素 背景
从长远来看,我并不是最炙手可热的jQuery家伙,我正试图去掉下面代码中重复的工作。虽然性能开销可能很小,而且可以忽略不计,但这更像是不想编写多次执行相同操作的蹩脚代码 基本上我有一个简单的发票表单,用户也可以添加多个项目 表单最初有4个输入:项目名称、项目价格、项目数量和总额如何将javascript事件处理程序附加到在javascript中创建的这些元素 背景,javascript,jquery,Javascript,Jquery,从长远来看,我并不是最炙手可热的jQuery家伙,我正试图去掉下面代码中重复的工作。虽然性能开销可能很小,而且可以忽略不计,但这更像是不想编写多次执行相同操作的蹩脚代码 基本上我有一个简单的发票表单,用户也可以添加多个项目 表单最初有4个输入:项目名称、项目价格、项目数量和总额 每当“价格”或“数量”字段触发更改事件时,都会计算总数 问题-部分解决(请参阅更新) 用户可以为第二项(或第三项、第四项、第五项等)添加额外的输入行 将事件处理程序附加到price和quantity字段的现有jav
- 每当“价格”或“数量”字段触发更改事件时,都会计算总数
- 将事件处理程序附加到
和price
字段的现有javascript已经运行,因此不会将侦听器附加到新添加的输入行quantity
/** Add additional item lines */
$('#add-item').click(function(e){
e.preventDefault();
/** clone first line and insert it */
$('.input-row:first').clone().insertAfter('.input-row:last');
/** clear the newly inserted inputs of values */
$(':input', '.input-row:last').val("");
/** ensure all item price and qty inputs have events attached to their change value */
$('input[name="item_qty[]"],input[name="item_price[]"]').on("change",function () {
var $container = $(this).closest('.form-group');
qty = Number($('input[name="item_qty[]"]',$container).val())||0,
price = Number($('input[name="item_price[]"]',$container).val())||0;
$('input[name="item_total[]"]',$container).val(qty * price);
$('input[name="item_total[]"]',$container).change();
});
/** Sum inputs for invoice total */
$('input[name="item_total[]"').change(function() {
var total = 0;
$.each($("[name='item_total[]']"), function(index, value) {
total += parseFloat($(this).val());
});
$("#total").val(total);
});
});
更新
因此,通过利用事件委托,事件可以传播(或冒泡)dom-谢谢大家!每当新父div中的一个输入发生变化时,我都会重新计算发票总额
<div id="invoice-items">
<input name /> <input quantity /> <input price /> <input total />
<input name /> <input quantity /> <input price /> <input total />
<input name /> <input quantity /> <input price /> <input total />
...
</div>
/** if any input rows change update the invoice total */
$('#invoice-items').on('change', 'input', function(event){
var total = 0;
$.each($("[name='item_total[]']"), function(index, value) {
total += parseFloat($(this).val());
});
$("#total").val(total);
});
我想我仍然需要的是在添加一行之后运行此代码的一些方法,或者遵循更干净的事件委派路线-某种方式只针对发生更改事件的行的item_total[]
?也许我可以捕获触发更改事件的元素的特定索引,并仅更新该索引处的项\u total[]
在这里大声想一想,我想如果我捕获事件并循环所有输入,直到找到与触发事件的元素匹配的元素,我就可以抓取下一个表单输入,名称为invoice\u total[]
,并对其进行更新我们去看看
更新
因此,我可以捕捉事件-快乐的日子:)
因此,我仍然不知道我更新了哪些item\u qty[]
元素,因此我不知道要更新哪些item\u total[]
元素
有什么建议吗 您要获取包装元素吗
<div>
<input />
<input />
</div>
$('div').on('change', 'input', function(){
// your magic here
});
$('div')。在('change','input',function()上{
//你的魔法在这里
});
这将对现在在场的两个人以及新元素起作用。为什么?简而言之:将事件绑定到存在的元素。您创建了一个新的事件,并对其进行了更改,但从未将事件绑定到新元素。这件事在树上冒着气泡,没有什么能抓住它 我的代码没有绑定到元素本身,您告诉它在
input
上监听其中的更改。新的元素进来了,你改变了它们,什么都没有发生,所以它会在树上冒泡。这就是最大的区别:这次我们告诉现有元素现在就做些什么。您希望将事件处理程序附加到克隆行。重点是什么?你在寻找更好的方式是对的,它是以活动授权的形式出现的。在它上面–它允许您将事件处理程序仅附加到一个父元素,该父元素将处理每个子
input
元素的change
事件(无论它们始终存在还是新添加).我刚刚对事件委派回答发表了评论-如果我可以将侦听器附加到div中的所有输入-很好,但是我如何针对特定输入来填充值。这种方式对我的发票总额非常有效,因为如果有任何需要更新的更改,那么单个行项目又如何呢?我是否将每一行包装在一个div中,并针对该div进行更改?好的,因此每一行输入现在都包含在一个父div中,我已将侦听器附加到该父div。好极了!我将首先尝试一下,只是为了确定-但我怀疑我会遇到问题-例如,当数量[0]发生变化时,如何使总数[0]==数量[0]*价格[0]
Ok,所以当任何一行发生变化时,观察所有输入并更新发票总额非常有效-我更新了我的问题,希望有人能提出一种方法,在该行发生变化时更新每一行。
event.currentTarget.attributes.name.nodeValue == 'item_qty[]'
<div>
<input />
<input />
</div>
$('div').on('change', 'input', function(){
// your magic here
});