问题
So imagine this scenario, I have a list and it has a bit of pagination going on, when the user clicks next, the link is hijacked by jQuery, it uses the $.ajax
function (of which I've provided below) to go and get the next page contents and display them in the original container. This includes the pagination links as well as we want them to update too.
The first page change works fine, but at this stage we've lost the bind between our link element and our jQuery rule:
$('#paging a').click(function(event) {
event.preventDefault();
getElementContents('#target_container','',$(this).attr('href'),false);
// arguements are (target element, data (for $ajax), url (for $ajax), highlight)
});
What options do I have to maintain the bind between the event and the function?
For reference, here is my wrapper function for $.ajax
:
var ajax_count = 0;
function getElementContents(target,data,url,highlight) {
if(url==null) {
url='/';
}
if(data==null) {
var data=new Array();
}
if(highlight==null || highlight==true) {
highlight=true;
} else {
highlight=false;
}
$.ajax({
url: url,
data: data,
beforeSend: function() {
/* if this is the first ajax call, block the screen */
if(++ajax_count==1) {
$.blockUI({message:'Loading data, please wait'});
}
},
success: function(responseText) {
/* we want to perform different methods of assignment depending on the element type */
if($(target).is("input")) {
$(target).val(responseText);
} else {
$(target).html(responseText);
}
/* fire change, fire highlight effect... only id highlight==true */
if(highlight==true) {
$(target).trigger("change").effect("highlight",{},2000)
}
},
complete: function () {
/* if all ajax requests have completed, unblock screen */
if(--ajax_count==0) {
$.unblockUI();
}
},
cache: false,
dataType: "html"
});
}
Thanks! :-)
EDIT
hmmm, just found this question... looking into it :-)
回答1:
try using jquery.live:
$('#paging a').live('click', function(event) {
event.preventDefault();
getElementContents('#target_container','',$(this).attr('href'),false);
// arguements are (target element, data (for $ajax), url (for $ajax), highlight)
});
if using jQuery 1.9 or above, .live no longer exists so you can use the .on function instead:
$(document).on('click', '#paging a', function (event) {
event.preventDefault();
getElementContents('#target_container','',$(this).attr('href'),false);
});
回答2:
Method .live() it was already removed on the 1.9 vertion of jQuery, instead they recommend use method .on().
But if you have a list of elements and you wrap those elements by his class name like $(".view-page").on("click", function(){}); and you load another chunk of elements (like a pagination page) of the same class, the binding will be lost.
The old .live() method resolved this ("Attach an event handler for all elements which match the current selector, now and in the future.") but you can do the same thing by using .on() in another form:
$(document).on("click", ".view-page", {}, function(event){
// anything you want to do...
});
This will not loose binding, even when chunks of elements change on your pagination zone, because your telling jQuery that everything that is in the DOM in anytime will have this behavior.
回答3:
Are your pagination links also being replaced via the ajax load? If so, they are new DOM elements, and the original pagination elements (which had the event handlers bound) are no longer present. If this is the case, check out jQuery's .live() method to bind your click handlers.
回答4:
You can re-bind the event in the callback function of the AJAX call.
complete: function () {
/* if all ajax requests have completed, unblock screen */
if(--ajax_count==0) {
$.unblockUI();
}
$('#paging a').click(function(event) {
event.preventDefault();
getElementContents('#target_container','',$(this).attr('href'),false);
// arguements are (target element, data (for $ajax), url (for $ajax), highlight)
});
}
来源:https://stackoverflow.com/questions/2773573/jquery-ajaxed-content-losing-its-bind