Estoy trabajando en una aplicación web donde el usuario puede navegar entre diferentes páginas (o 'vistas parciales') que se cargan con AJAX. Lo hice para que cuando el usuario presione el botón de avance y retroceso en el navegador, la aplicación devuelva la vista correcta según la URL que contenga la barra de direcciones en ese momento.
Mi problema: cuando navego lentamente presionando el botón de avance y retroceso en el navegador, funciona normalmente. Pero cuando presiono repetidamente el botón Atrás o Adelante, carga varias vistas dentro de la aplicación.
Mi pregunta: ¿Hay alguna manera de evitar que se carguen múltiples vistas en la aplicación y solo cargue la vista que se supone que debe cargar?
Mi código:
$(window).on("popstate", function (e) { $(".UserNavigation li").removeClass("active"); LoadContent.init(); }) var LoadContent = { init: function (url, query) { var Content = { } var PathName; if (url == null) { PathName = window.location.pathname; Content.url = "ContentArea/" + PathName; } else { var Controller = "ContentArea/" Content.url = Controller + url } if (query) Content.query = query LoadContent.Loading(this); xhr = $.ajax({ type: "POST", url: Content.url, data: { query: Content.query, type: 0 }, success: function (data) { LoadContent.ApplyContent(data); }, error: function () { }, complete: function (data) { if (url != null) LoadContent.UpdateHistory(data, url); } }) }, ApplyContent: function (data) { $("#ContentLoading").animate({ opacity: 0 }, 200, function () { $("#ContentLoading").addClass("hidden"); $("#ContentArea").append(data).addClass("visible"); LoadContent.UpdateMenu(); }) return this; }, Loading: function () { $("#ContentArea").children().remove(); $("#ContentLoading").removeClass("hidden"); $("#ContentArea").removeClass("visible"); $("#ContentLoading").animate({ opacity: 1 }, 200) }, UpdateHistory: function (data, url) { var DataToSave = { StateURL: url, } history.pushState(DataToSave.StateURL, url, url) }, UpdateMenu: function () { var CurrentPath = window.location.pathname; $(".UserNavigation li").removeClass("active"); $("[href='" + CurrentPath + "']").parent().addClass("active"); } }En la siguiente parte
ApplyContent: function (data) { $("#ContentLoading").animate({ opacity: 0 }, 200, function () { $("#ContentLoading").addClass("hidden"); $("#ContentArea").append(data).addClass("visible"); LoadContent.UpdateMenu(); }) return this; }, Cambia .append() por .html() . Esto evitará que el contenido adicional llene más espacio, pero reemplazará completamente el html de #ContentArea .
Como dijo Parth, también debe abortar las solicitudes Ajax en ejecución y comenzar una nueva. Esto no evitará que el servidor le envíe sus resultados, por lo que es mejor cancelar también todas las solicitudes antiguas en el servidor cuando envíe otras nuevas.
En su caso, la respuesta de ajax carga los datos, entonces, ¿qué sucede si envía una solicitud múltiple? Por supuesto, los datos de ajax (ver) reemplazan el anterior. Por lo tanto, debe detener la solicitud de ajax anterior
if (typeof this.xhr !== 'undefined') this.xhr.abort();el código anterior detiene la solicitud anterior de ajax
this.xhr = $.ajax({ type: "POST", url: Content.url, data: { query: Content.query, type: 0 }, success: function (data) { LoadContent.ApplyContent(data); }, error: function () { }, complete: function (data) { if (url != null) LoadContent.UpdateHistory(data, url); } })