ajax调用后不会触发Jquery事件

IT技术 javascript jquery html dom-events
2021-01-14 00:31:48

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

<div id="container">

在页面加载时。每条记录都是带有“删除”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个回答

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

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

对此有几种可能的解决方案。

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)更优雅的处理方式:使用jQuery 的 .on() 方法有了它,您就可以将事件处理程序绑定到事件目标以外的元素——即永远不会从页面中删除的元素。

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

一些进一步的解释:

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

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

此外,值得注意的是,由于事件通过 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 ....
        // This will never execute, should've used '#container-2', or 'body', or 'document' instead of '#container-1'
    });
</script>

bodydocument元素通常是安全的选择,因为通常每个页面上的元素的后裔。

你——是——那个——男人!我在使用 socket.io 事件替换 dom 的部分时遇到了这个问题,当幻灯片完成滚动时,我的引导轮播不会触发我需要的事件,我已经将事件驱动的 js 包装在 bindsomething() 函数中,如您所描述的,并且它都在运行现在好了,谢谢!
2021-03-22 00:31:48
只是一个问题和一个评论,虽然我看到这是一个旧帖子。我在使用 function submitorderhandler() { $(document).on('click', '#xxx", function(e) { 时遇到了很多麻烦
2021-03-25 00:31:48
哦,我的上帝.... 我正在为此苦苦挣扎...我添加了一个 ajaxComplete 函数来处理它,并检查事件处理程序是否已经存在并且我仍然有问题。你救了我的一天!
2021-03-27 00:31:48
在这件事上购买虚拟啤酒的选项在哪里?
2021-04-02 00:31:48
哇。优秀的解决方案。由于 Google 的新自动播放政策,我在 Chrome 中遇到了 SoundCloud 自动播放问题。这设法解决了问题。我添加了一个标志,以便当窗口加载时,bindButtonClick 函数被传递 0,因此事件处理程序被阻止执行。但是,在 Ajax 调用中,我传递了 1,事件处理程序开始工作!
2021-04-04 00:31:48

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

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

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

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

一旦加载了动态加载的内容并运行了替换命令,事件将被映射并且代码将正常运行。

请在您的答案中添加一些解释,以便其他人可以从中学习。是什么让您认为任何绑定到元素的处理程序div在替换内容后仍然绑定?
2021-04-12 00:31:48