“click”监听器多次执行

时间:2013-04-17 07:18:05

标签: javascript jquery html

我正在尝试创建使用ajax创建行的表。问题是,当我根据类名分配“click”监听器时,它会被多次调用

我的代码是

function fn_getAlertRules(parentRowId) {
    $.ajax({
        type: "GET",
        url: anyURL,
        contentType: "application/json",
        dataType: "json"
    }).done(function(data) {
        // create row to add to parent table's row
        var s_rulesHtmlString = '<tr><td colspan="3" class="rules-parent-tr"><table><tbody>';
        $.each(data, function(i, name) {
        s_rulesHtmlString += '<tr class="rule-tr">';
        s_rulesHtmlString += '<td class="eventid-td">Rule ID:'+ name.RuleId+'<span>' + name.OccuredEventId + '</span></td>';
        s_rulesHtmlString += '<td>' + name.Name + '</td><td>' + name.RuleDate + '</td>';
        s_rulesHtmlString += '</tr>';
        });
        s_rulesHtmlString += '</tbody></table></td></tr>';
        // add row below parent tr
        $(parentRowId).parent().after(s_rulesHtmlString);
        $(".rule-tr").on("click", "td", function(event) {
            // this code blocks get executed multiple times
        });
    });
}

任何人都可以告诉我,为什么它被多次调用?

5 个答案:

答案 0 :(得分:2)

那是因为您有多个表行,并为其分配了相同的类。如果您只想对所单击的项目执行该操作,请为其指定唯一ID。

答案 1 :(得分:2)

您在每个事件中绑定click事件(循环),并且事件被绑定的次数与循环执行次数相同,这就是您重复点击事件的原因。您可以将click事件委托给要添加的元素的父元素,或者在ajax调用之前将document委托给事件,并且事件将自动绑定到在done函数中添加的动态添加元素。您可以在here

上阅读有关事件委派的更多信息
  

委派事件的优势在于它们可以处理来自的事件   稍后添加到文档中的后代元素。通过   选择一个保证在当时存在的元素   委托事件处理程序附加,您可以使用委托事件   避免频繁附加和删除事件处理程序的需要。 Reference

function fn_getAlertRules(parentRowId) {
    $(document).on("click", ".rule-tr td", function(event) {
       // this code blocks get executed multiple times 
    });

    $.ajax({
        type: "GET",
        url: anyURL,
        contentType: "application/json",
        dataType: "json"
    }).done(function(data) {
        // create row to add to parent table's row
        var s_rulesHtmlString = '<tr><td colspan="3" class="rules-parent-tr"><table><tbody>';
        $.each(data, function(i, name) {
        s_rulesHtmlString += '<tr class="rule-tr">';
        s_rulesHtmlString += '<td class="eventid-td">Rule ID:'+ name.RuleId+'<span>' + name.OccuredEventId + '</span></td>';
        s_rulesHtmlString += '<td>' + name.Name + '</td><td>' + name.RuleDate + '</td>';
        s_rulesHtmlString += '</tr>';
        });
        s_rulesHtmlString += '</tbody></table></td></tr>';
        // add row below parent tr
        $(parentRowId).parent().after(s_rulesHtmlString);       
    });
}

答案 2 :(得分:1)

我认为解决方案(也可以优化性能)是使用delegation。因此,您可以在父行(或表)上添加单个事件处理程序,并根据event.target对象执行操作。

UPDATE:此外,请注意选择器$(".rule-tr")将事件处理程序追加到具有不同parent_id的行,以便更好的解决方案可能是$(parent_Id + " .rule-tr"),假设parent_id是一个字符串以"#parent_id"

的形式

答案 3 :(得分:0)

仅在ajax

之后将点击事件连接到最后一个<tr>
$(".rule-tr :last").on("click", "td", function(event) {
            // this code blocks get executed multiple times
        });         

答案 4 :(得分:0)

也许您可以尝试避免重复绑定点击事件

$(".rule-tr").unbind();
$(".rule-tr").on("click", "td", function(event) {
            // this code blocks get executed multiple times
        });