Javascript ajax调用后不会触发Jquery事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13767919/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jquery Event won't fire after ajax call
提问by Matthew Colley
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();
}
});
});
});
回答by Jason Fingar
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 delegationto 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 delegatemethod 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 ....
// This will never execute, should've used '#container-2', or 'body', or 'document' instead of '#container-1'
});
</script>
The bodyor documentelements are usually safe choices since typically every element on the page is a descendant.
该body或document元素通常是安全的选择,因为通常每个页面上的元素的后裔。
回答by Srikanth Srikanth
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.
一旦加载了动态加载的内容并运行了替换命令,事件将被映射并且代码将正常运行。
回答by SScotti
My comment is too long, sorry.
我的评论太长了,抱歉。
Just a question and a comment, although I see that this is an old post. I have had a lot of trouble using: $(document).on('click', '#xxx", function(e) { }); to attach handlers to content returned using AJAX, vs. using a function () { $('#xxx).on('click', function(e) { }); } and calling that after the AJAX call returns with success. Is there some sort of trick or guideline for using that method ? I get the delegation involved, and I have tried using that but it does not often work. I could try delegating to the enclosing element. Maybe it does not bubble up to the document or the body for some reason ?
只是一个问题和一个评论,虽然我看到这是一个旧帖子。我在使用时遇到了很多麻烦: $(document).on('click', '#xxx", function(e) { }); 将处理程序附加到使用 AJAX 返回的内容,而不是使用函数 () { $('#xxx).on('click', function(e) { }); } 并在 AJAX 调用成功返回后调用它。是否有使用该方法的某种技巧或指南?我得到了委托涉及,我曾尝试使用它,但它通常不起作用。我可以尝试委托给封闭元素。也许由于某种原因它没有冒泡到文档或正文?

