Ich habe ein Web - App erstellt , die die nutzen history pushStateund replaceStatewährend Methoden navigieren , um durch die Seiten auch die Geschichte zu aktualisieren.
Das Skript selbst funktioniert fast perfekt; Es lädt Seiten korrekt und wirft Seitenfehler aus, wenn sie geworfen werden müssen. Ich habe jedoch ein seltsames Problem festgestellt pushState, bei dem mehrere doppelte Einträge in den Verlauf verschoben (und Einträge davor ersetzt) werden.
Nehmen wir zum Beispiel an, ich mache Folgendes (in der richtigen Reihenfolge):
Laden Sie index.php hoch (Verlauf lautet: Index)
Navigieren Sie zu profile.php (Verlauf lautet: Profil, Index)
Navigieren Sie zu search.php (Verlauf lautet: Suchen, Suchen, Indexieren)
Navigieren Sie zu dashboard.php
Dann ist es schließlich das, was in meiner Geschichte auftauchen wird (in der Reihenfolge der letzten bis ältesten):
Armaturenbrett
Armaturenbrett
Armaturenbrett Suchindex
Das Problem dabei ist, dass ein Benutzer, wenn er auf die Vorwärts- oder Rückwärtsschaltflächen klickt, entweder auf die falsche Seite umgeleitet wird oder mehrmals klicken muss, um einmal zurück zu gehen. Das, und es macht keinen Sinn, wenn sie ihre Geschichte überprüfen.
Das habe ich bisher:
var Traveller = function(){
this._initialised = false;
this._pageData = null;
this._pageRequest = null;
this._history = [];
this._currentPath = null;
this.abort = function(){
if(this._pageRequest){
this._pageRequest.abort();
}
};
// initialise traveller (call replaceState on load instead of pushState)
return this.init();
};
/*1*/Traveller.prototype.init = function(){
// get full pathname and request the relevant page to load up
this._initialLoadPath = (window.location.pathname + window.location.search);
this.send(this._initialLoadPath);
};
/*2*/Traveller.prototype.send = function(path){
this._currentPath = path.replace(/^\/+|\/+$/g, "");
// abort any running requests to prevent multiple
// pages from being loaded into the DOM
this.abort();
return this._pageRequest = _ajax({
url: path,
dataType: "json",
success: function(response){
// render the page to the dom using the json data returned
// (this part has been skipped in the render method as it
// doesn't involve manipulating the history object at all
window.Traveller.render(response);
}
});
};
/*3*/Traveller.prototype.render = function(data){
this._pageData = data;
this.updateHistory();
};
/*4*/Traveller.prototype.updateHistory = function(){
/* example _pageData would be:
{
"page": {
"title": "This is a title",
"styles": [ "stylea.css", "styleb.css" ],
"scripts": [ "scripta.js", "scriptb.js" ]
}
}
*/
var state = this._pageData;
if(!this._initialised){
window.history.replaceState(state, state.title, "/" + this._currentPath);
this._initialised = true;
} else {
window.history.pushState(state, state.title, "/" + this._currentPath);
}
document.title = state.title;
};
Traveller.prototype.redirect = function(href){
this.send(href);
};
// initialise traveller
window.Traveller = new Traveller();
document.addEventListener("click", function(event){
if(event.target.tagName === "a"){
var link = event.target;
if(link.target !== "_blank" && link.href !== "#"){
event.preventDefault();
// example link would be /profile.php
window.Traveller.redirect(link.href);
}
}
});
Jede Hilfe wird geschätzt,
Prost.
updateHistoryFunktion hinzufügen . Nun updateHistorykann zweimal genannt zu werden , 1., wenn Sie die Initialisierung von Reisenden ( window.Traveller = new Traveller();, constructor-> init-> send-> render-> updateHistory), dann auch redirectvon der clickeventlistener. Ich habe es nicht getestet, nur wild geraten, also füge es als Kommentar und nicht als Antwort hinzu.