Javascript 如何对动态添加的元素执行动态操作?
我的目标: 使用JS/Jquery动态填写“执行者付款”表 对于表中每个动态添加的行,其中一个数据单元包含一个下拉框。 当选择某个选项时,此下拉框应使同一单元格中的另一个下拉框可见。否则,第二个下拉列表将不可见。 在其他地方,我通过一个toggleVisible函数来实现隐藏/显示动态,该函数只添加由css标记的自定义类来隐藏或显示元素。 有关守则: 我要填充的表:Javascript 如何对动态添加的元素执行动态操作?,javascript,jquery,html,Javascript,Jquery,Html,我的目标: 使用JS/Jquery动态填写“执行者付款”表 对于表中每个动态添加的行,其中一个数据单元包含一个下拉框。 当选择某个选项时,此下拉框应使同一单元格中的另一个下拉框可见。否则,第二个下拉列表将不可见。 在其他地方,我通过一个toggleVisible函数来实现隐藏/显示动态,该函数只添加由css标记的自定义类来隐藏或显示元素。 有关守则: 我要填充的表: <table id='performer-payments' class='performer-profile paymen
<table id='performer-payments' class='performer-profile payments-table'>
<tr>
<th> Period </th>
<th> Amount </th>
<th> Paid? </th>
</tr>
</table>
这至少有两个问题:
支付转移期-。。。即使在第一个选择框中选择了“传输”选项,也不会显示选择框。从调试工作来看,我认为可能是支付转移期-。。由于某种原因,它还不是一个有效的对象,或者类似的东西。
显然,实际上,onchange事件被触发N次N=周期数,因为我只是告诉程序在表中的内容发生更改时触发。我想它触发只为相关下拉列表,但当我试图添加付款状态-。。。作为.on函数的选择器,它使它从不触发。
注意:一般来说,我欢迎对此的反馈——我是一名经验丰富的程序员,但对HTML/JS/Jquery的使用经验很少。此外,我已经决定不在这个项目中使用模板,因为我正在尝试学习基础知识,所以如果您看到我“动态”将行添加到表中的方式,我很抱歉,但这部分是故意的
除此之外,如果这里有不清楚的地方,请要求澄清
编辑:以下是数据结构的相关部分:
data = {
'Performers': {
'Dira Klaggen': {
'Payments': {
'Q1': 'Paid',
'Q2': 'Paid',
'Q3': 'Unpaid'
},
},
'Holden Bolden': {
'Payments': {
'Q2': 'Transferred to Q3',
'Q3': 'Unpaid'
}
},
'Manny Joe': {
'Payments': {
'Q1': 'Paid',
'Q2': 'Unpaid',
'Q3': 'Unpaid',
}
}
},
'Periods': [
'Q1',
'Q2',
'Q3'
]
}
您没有将更改处理程序附加到正确的元素。我应该是第一个被选中的人。。。而不是整张桌子
请尝试此更改处理程序:
第二种方法:
您可以通过在第一次选择时使用类而不是复杂的唯一id来简化这一点
假设您使用类付款状态:
处理程序将是:
$('#performer-payments').on('change', '.payment-status', function(){
if ($(this).val() == 'transfer') {
$(this).next('select').show();
} else {
$(this).next('select').hide();
}
});
这个处理程序可能不在行附加循环中,因为它使用了。让我们通过执行以下操作来清理代码: 使用类而不是丑陋的ID 使用或隐藏输入字段来保存额外信息 用于绑定动态创建的元素。在事件处理程序中,使用方法根据当前元素限制搜索范围 让我们应用这些东西 像这样构建每一行。{PLACEHOLDER}是将变量内容放入代码中的位置
<tr>
<td>{PERIOD}</td>
<td>{AMOUNT} $ </td>
<td>
<div class='performer-profile payment-status'>
{SOMETHING-RELATING-TO-PERFORMER-PAYMENT-PERIOD}
</div>
<!-- remove ID -->
<!-- store performer and period in data-attributes -->
<select class='perfomer-profile hidden-onload displayNone payment-status-menu' data-performer='{PERFORMER}' data-period='{PERIOD}'>
<option value='paid'>Paid</option>
<option value='unpaid'>Unpaid</option>
<option value='transfer'>Transfer to...</option>
</select>
<!-- remove ID -->
<select class='performer-profile hidden-onload displayNone payment-period-menu'>
<option value='{PERIOD}'>{PERIOD}</option>
<option value='{PERIOD}'>{PERIOD}</option>
<option value='{PERIOD}'>{PERIOD}</option>
<!-- etc -->
</select>
</td>
</tr>
看起来你不需要2个。但如果您这样做,则在事件处理程序中,使用获取其performer和period值。您也可以这样做。您的数据样本将有助于重新创建问题。您的意图是好的?不幸的是,这与我尝试进一步指定“开”选择器时面临的问题相同:它从未触发。请尝试第二种方法。。。添加一个console.logChange!就在if.Great之前,您和Louys的答案似乎都表明,在JS中,按唯一ID进行选择不是一种方式,而是使用树遍历,然后,我猜,如果您需要额外的数据,则使用数据属性。不过,要明确的是,您在这里包含的数据属性纯粹是信息性的,对吗?与中一样,似乎不需要数据属性来解决这个特定问题?@Yourik是的,没错。检查我的最后一段。似乎你什么都不需要它。唯一的ID可能是一种方式。。。但在这种附加循环的情况下,这并不是最容易做到的事情。结果是一个丑陋的代码在将来更难维护。@Louyspatricebesette你是对的。就个人而言,我避免在循环中创建事件处理程序。大多数时候,如果您正确地使用jQuery方法,您不需要这样做。@Mikey:我完全同意;
$('#performer-payments').find('#payment-status-' + performer + '-' + period).on('change', function(){
if ($(this).val() == 'transfer') {
$(this).next('select').show();
} else {
$(this).next('select').hide();
}
});
$('#performer-payments').on('change', '.payment-status', function(){
if ($(this).val() == 'transfer') {
$(this).next('select').show();
} else {
$(this).next('select').hide();
}
});
<tr>
<td>{PERIOD}</td>
<td>{AMOUNT} $ </td>
<td>
<div class='performer-profile payment-status'>
{SOMETHING-RELATING-TO-PERFORMER-PAYMENT-PERIOD}
</div>
<!-- remove ID -->
<!-- store performer and period in data-attributes -->
<select class='perfomer-profile hidden-onload displayNone payment-status-menu' data-performer='{PERFORMER}' data-period='{PERIOD}'>
<option value='paid'>Paid</option>
<option value='unpaid'>Unpaid</option>
<option value='transfer'>Transfer to...</option>
</select>
<!-- remove ID -->
<select class='performer-profile hidden-onload displayNone payment-period-menu'>
<option value='{PERIOD}'>{PERIOD}</option>
<option value='{PERIOD}'>{PERIOD}</option>
<option value='{PERIOD}'>{PERIOD}</option>
<!-- etc -->
</select>
</td>
</tr>
$(function () {
// ...
for (period in data['Performers'][performer]['Payments']) {
// build and append row
}
// create delegated event handler once and outside FOR loop
$(document).on('change', '.payment-status-menu', function () {
// get the current status menu
var statusMenu = $(this);
// find its related period menu
var periodMenu = statusMenu.closest('tr').find('.payment-period-menu');
// toggle its visibility
periodMenu.toggle(this.value == 'Transfer');
// of course, this could be a one-liner
//$(this).closest('tr').find('.payment-period-menu').toggle(this.value == 'Transfer');
});
});