Bueno... He estado mirando el código con más detalle y se me ha ocurrido alguna cosa más.
Claramente hay que eliminar la llamada síncrona como sea. Además, ¿has probado lo de cancelar? ¿Funciona bien?
Lo digo porque puede que funcione, pero es un comportamiento en el que no deberías confiar. Si la petición es síncrona, el código se debe parar ahí hasta que se recibe la respuesta. Aunque se genere por otro lado el evento que mande el abort(), el navegador no tiene un modo limpio de terminar la petición y continuar la ejecución del código, pero tampoco tiene un modo limpio de parar la ejecución del resto del código. Con una petición asíncrona, basta eliminar la petición. Se desconecta, no llega respuesta, nunca salta el evento readystatechange (*) y no hay ningún problema.
(*) En realidad sí salta, porque se resetea a 0. Pero bueno, ese ya es otro asunto.
Bueno, a lo que iba. Creo que habría que hacer algo más o menos así:
Código javascript
:
Ver originaljQuery.fn.cp = function(url,data,precall,postcall){
this.each( function(){
if($(this).attr("title")=="x"){
return;
}
$(this).attr("title","x");
var im='<center><img id="il'+this.id+'" src="../images/loading.gif" alt="cargando" \/><br \/>'+
'<br \/><input type="button" value="Detener" id="btn'+this.id+'"\/><\/center>';
$(this).fadeOut("fast",function(){
var h=new ofset(); h=h.H(this.id);
$(this).html('<table width="100%" border="0" height="'+h+'" id="ttt"><tr><td valign="middle" id="td'+this.id+'">'+im+'<\/td><\/tr><\/table>');
$(this).show();
var conte=this;
$(this).before('<div id="d_aux'+this.id+'" style="display:none" ><\/div>');
var res;
$("#btn"+this.id).click(function(){
res.onreadystatechange = function() {};
res.abort();
$(this).before("<span class='alerta'>Carga Detenida<\/span>");
$("#"+this.id+",#il"+conte.id+",#d_aux"+conte.id).remove();
$(conte).removeAttr("title");
return false;
});
res=$.ajax({
type: "POST",
cache: false,
async: true,
url: url,
data: data,
success: function(res) {
if(precall){res=precall(res);}
$("#d_aux"+this.id).html(res);
var h=new ofset(); h=h.H("d_aux"+this.id);
$("#td"+this.id).empty();
$(this).animate({height:h},"normal",function(){
$("#d_aux"+conte.id).fadeIn("fast");
$(this).remove();
$("#d_aux"+conte.id).attr("id",conte.id);
$(this).removeAttr("title")
if(postcall){postcall()}
});
}
});
});
});
}
Lo he puesto un poco deprisa y habría que revisarlo y probarlo, claro. Miralo tú un poco por esta parte, ok?
Ah, otra cosa... los nombre "precallback" y "postcallback" a mi personalmente no me quedan muy claros porque en realidad se llaman los dos después de la petición XHR, ¿no? Quizá sería mejor ponerles nombres como... "processDataCallback" y... no sé, "finalizeCallback" o alguna cosa similar.