ajax调用后,Jquery事件不会触发

时间:2022-12-03 20:21:20

This is a rather strange issue with jquery. I am loading a div

这是jquery的一个相当奇怪的问题。我正在加载div

<div id="container">

on page load. Each record is tabular data with a 'delete' ajax function associated with it. When the page loads and clicking the 'delete' link, the ajax call fires off just fine. However, once the event is fired, the data is returned from the ajax call, and the div is populated with data (but the page does not refresh or reload) When I click the link again, the ajax script will not fire. Here is my code:

在页面加载。每条记录都是表格数据,带有与之关联的“删除”ajax函数。当页面加载并单击“删除”链接时,ajax调用就会触发。但是,一旦事件被触发,数据将从ajax调用返回,div将填充数据(但页面不会刷新或重新加载)当我再次单击该链接时,ajax脚本将不会触发。这是我的代码:

$(document).ready(function() {
    $("button.done").button({
    }).click(function() {
        var BatchID = $("input#BatchID").val();
        var Amount = $("input#Amount").val();
        var Name = $("input#CheckName").val();
        var Check_Number = $("input#Check_Number").val();
        var Company = $("select#Company").val();
        var Department = $("select#Department").val();
        $.ajax({
            type: 'GET',
            url: '/app/usagCheckEntryWS.html',
            data: {
                "BatchID" : BatchID,
                "Amount" : Amount,
                "Name" : Name,
                "Check_Number" : Check_Number,
                "Company" : Company,
                "Department" : Department
            },
            success: function (data) {
                    var ang = '';
                    var obj = $.parseJSON(data);
                    $.each(obj, function() {
                       ang += '<table><tr><td width="45">' + this["RefID"] + '</td><td width="140">' + this["Name"] + '</td><td width="95">' + this["CheckNumber"] + '</td><td align="right" width="70">$' + this["Amount"] + '</td><td width="220" style="padding-left: 15px;">' + this["Description"] + '</td><td><div class="delete" rel="' + this["RefID"] + '"><span>Delete</span></div></td></tr></table>';
                    });
                    $('#container').html(ang);
                    $("input#Amount").val('');
                    $("input#CheckName").val('');
                    $("input#Check_Number").val('');
                    $("select#Company").val('MMS');
                    $("th#dept").hide();
                    $('input#CheckName').focus();
            }
        });
    });
});

2 个解决方案

#1


130  

When you remove an element and then replace it (via javascript), it loses any event bindings that were added to it on page load.

删除元素然后替换它(通过javascript)时,它会丢失在页面加载时添加到它的任何事件绑定。

(This also applies to content added to the page after page load - i.e. ajax loaded content)

(这也适用于页面加载后添加到页面的内容 - 即加载了ajax的内容)

There are several possible solutions for this.

有几种可能的解决方案。

1) Encapsulate your "binding" code and call it both on page load and immediately after the element in question gets added back to the page. For example:

1)封装你的“绑定”代码并在页面加载时调用它,并在有问题的元素被添加回页面后立即调用它。例如:

$(document).ready(function(){
    // bind event handlers when the page loads.
    bindButtonClick();
});

function bindButtonClick(){
    $('.myClickableElement').click(function(){
        ... event handler code ...
    });
}

function updateContent(){
    $.ajax({
        url : '/ajax-endpoint.php',
        data : {'onMyWay' : 'toServer'},
        dataType : 'html',
        type : 'post',
        success : function(responseHtml){
            // .myClickableElement is replaced with new (unbound) html element(s)
            $('#container').html(responseHtml);

            // re-bind event handlers to '.myClickableElement'
            bindButtonClick();  
        }
    });
}

2) The more elegant way to handle this: use jQuery's .on() method. With it, you are able to bind event handlers to elements other than the event target - i.e. an element that never gets removed from the page.

2)处理这个问题的更优雅的方法:使用jQuery的.on()方法。通过它,您可以将事件处理程序绑定到事件目标以外的元素 - 即永远不会从页面中删除的元素。

$(document).ready(function(){
    $('body').on('click','.myClickableElement',function(){
        ... event handler code ....
    });
});

Some further explanation:

进一步说明:

The .on() method uses event delegation to tell a parent element to retain your event handler code (3rd argument), and fire it when the event target (2nd argument) has a certain type of event (1st argument) performed on it.

.on()方法使用事件委托来告诉父元素保留事件处理程序代码(第三个参数),并在事件目标(第二个参数)对其执行某种类型的事件(第一个参数)时触发它。

If you are using a version of jQuery prior to 1.7 use the now deprecated delegate method which essentially does the same thing.

如果您使用1.7之前的jQuery版本,请使用现在已弃用的委托方法,该方法基本上执行相同的操作。

Also, it is worth noting that because of the way events "bubble up" through the dom tree, the event target (2nd argument of .on() method) must be a descendant of the delegating element (jQuery object's selector). For example, the following would NOT work

此外,值得注意的是,由于事件通过dom树“冒泡”的方式,事件目标(.on()方法的第二个参数)必须是委托元素(jQuery对象的选择器)的后代。例如,以下内容不起作用

<div id="container-1">
    <div>
        <div id="another-div">
            Some Stuff
        </div>
    </div>
</div>

<div id="container-2">
    <a id="click-me">Event Target!!!</a>
</div>

<script type="text/javascript">
    $('#container-1').on('click','#click-me',function(){
        ... event handler code ....
    });
</script>

The body or document elements are usually safe choices since typically every element on the page is a descendant.

正文或文档元素通常是安全的选择,因为页面上的每个元素通常都是后代。

#2


1  

You can enclose the event script in DIV and run a Replaceall command after dynamically loading the content.

您可以将事件脚本包含在DIV中,并在动态加载内容后运行Replaceall命令。

<div class="somescript">
-- Event Script that you want to map with dnamically added content
<div>

-- Dynamically load your content and run the below command after it.

- 动态加载内容并在其后运行以下命令。

$(".somescript").replaceAll($(".somescript"));

Once the dynamically loaded content is loaded and replace command has been run, the events will be mapped and code will run fine.

加载动态加载的内容并运行replace命令后,将映射事件并且代码将正常运行。

#1


130  

When you remove an element and then replace it (via javascript), it loses any event bindings that were added to it on page load.

删除元素然后替换它(通过javascript)时,它会丢失在页面加载时添加到它的任何事件绑定。

(This also applies to content added to the page after page load - i.e. ajax loaded content)

(这也适用于页面加载后添加到页面的内容 - 即加载了ajax的内容)

There are several possible solutions for this.

有几种可能的解决方案。

1) Encapsulate your "binding" code and call it both on page load and immediately after the element in question gets added back to the page. For example:

1)封装你的“绑定”代码并在页面加载时调用它,并在有问题的元素被添加回页面后立即调用它。例如:

$(document).ready(function(){
    // bind event handlers when the page loads.
    bindButtonClick();
});

function bindButtonClick(){
    $('.myClickableElement').click(function(){
        ... event handler code ...
    });
}

function updateContent(){
    $.ajax({
        url : '/ajax-endpoint.php',
        data : {'onMyWay' : 'toServer'},
        dataType : 'html',
        type : 'post',
        success : function(responseHtml){
            // .myClickableElement is replaced with new (unbound) html element(s)
            $('#container').html(responseHtml);

            // re-bind event handlers to '.myClickableElement'
            bindButtonClick();  
        }
    });
}

2) The more elegant way to handle this: use jQuery's .on() method. With it, you are able to bind event handlers to elements other than the event target - i.e. an element that never gets removed from the page.

2)处理这个问题的更优雅的方法:使用jQuery的.on()方法。通过它,您可以将事件处理程序绑定到事件目标以外的元素 - 即永远不会从页面中删除的元素。

$(document).ready(function(){
    $('body').on('click','.myClickableElement',function(){
        ... event handler code ....
    });
});

Some further explanation:

进一步说明:

The .on() method uses event delegation to tell a parent element to retain your event handler code (3rd argument), and fire it when the event target (2nd argument) has a certain type of event (1st argument) performed on it.

.on()方法使用事件委托来告诉父元素保留事件处理程序代码(第三个参数),并在事件目标(第二个参数)对其执行某种类型的事件(第一个参数)时触发它。

If you are using a version of jQuery prior to 1.7 use the now deprecated delegate method which essentially does the same thing.

如果您使用1.7之前的jQuery版本,请使用现在已弃用的委托方法,该方法基本上执行相同的操作。

Also, it is worth noting that because of the way events "bubble up" through the dom tree, the event target (2nd argument of .on() method) must be a descendant of the delegating element (jQuery object's selector). For example, the following would NOT work

此外,值得注意的是,由于事件通过dom树“冒泡”的方式,事件目标(.on()方法的第二个参数)必须是委托元素(jQuery对象的选择器)的后代。例如,以下内容不起作用

<div id="container-1">
    <div>
        <div id="another-div">
            Some Stuff
        </div>
    </div>
</div>

<div id="container-2">
    <a id="click-me">Event Target!!!</a>
</div>

<script type="text/javascript">
    $('#container-1').on('click','#click-me',function(){
        ... event handler code ....
    });
</script>

The body or document elements are usually safe choices since typically every element on the page is a descendant.

正文或文档元素通常是安全的选择,因为页面上的每个元素通常都是后代。

#2


1  

You can enclose the event script in DIV and run a Replaceall command after dynamically loading the content.

您可以将事件脚本包含在DIV中,并在动态加载内容后运行Replaceall命令。

<div class="somescript">
-- Event Script that you want to map with dnamically added content
<div>

-- Dynamically load your content and run the below command after it.

- 动态加载内容并在其后运行以下命令。

$(".somescript").replaceAll($(".somescript"));

Once the dynamically loaded content is loaded and replace command has been run, the events will be mapped and code will run fine.

加载动态加载的内容并运行replace命令后,将映射事件并且代码将正常运行。