Saya telah membuat aplikasi web yang menggunakan history pushStatedanreplaceState metode untuk menavigasi halaman sambil memperbarui sejarah.
Script itu sendiri hampir berfungsi dengan sempurna; itu akan memuat halaman dengan benar, dan membuang kesalahan halaman ketika mereka perlu dilempar. Namun, saya perhatikan ada masalah aneh di mana pushStateakan mendorong banyak entri, duplikat (dan mengganti entri sebelumnya) ke riwayat.
Sebagai contoh, katakanlah saya melakukan hal berikut (secara berurutan):
Muat index.php (sejarah akan menjadi: Indeks)
Navigasikan ke profile.php (riwayatnya adalah: Profil, Indeks)
Arahkan ke search.php (riwayatnya adalah: Cari, Cari, Indeks)
Arahkan ke dashboard.php
Lalu akhirnya, inilah yang akan muncul dalam sejarah saya (dalam urutan terbaru hingga tertua):
Dashboard
Dashboard
Dashboard
Cari
Indeks
Masalahnya adalah ketika pengguna mengklik tombol maju atau mundur, mereka akan diarahkan ke halaman yang salah, atau harus mengklik beberapa kali untuk kembali sekali. Itu, dan tidak masuk akal jika mereka pergi dan memeriksa sejarah mereka.
Inilah yang saya miliki sejauh ini:
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);
}
}
});
Semua bantuan dihargai,
Ceria.
updateHistoryfungsi Anda . Sekarang, updateHistorymungkin dipanggil dua kali, 1, ketika Anda menginisialisasi Traveler ( window.Traveller = new Traveller();, constructor-> init-> send-> render-> updateHistory), kemudian juga oleh redirectdari clickeventListener. Saya belum mengujinya, hanya menebak-nebak, jadi menambahkannya sebagai komentar dan bukan jawaban.