Geçmişi de güncellerken sayfalarda gezinmek için history pushStateve replaceStateyöntemlerini kullanan bir web uygulaması oluşturdum .
Betiğin kendisi neredeyse mükemmel çalışır; sayfaları doğru yükler ve atılmaları gerektiğinde sayfa hataları atar. Ancak, pushStategeçmişe birden fazla, yinelenen girişleri (ve daha önce girişleri değiştirecek) itecek garip bir sorun fark ettim .
Örneğin, aşağıdakileri yaptığımı varsayalım (sırayla):
İndex.php dosyasını yükle (geçmiş: Dizin olacak)
Profile.php dosyasına gidin (geçmiş: Profil, Dizin)
Search.php dosyasına gidin (geçmiş: Arama, Arama, Dizin)
Dashboard.php adresine gidin
Sonunda, tarihimde ortaya çıkacak olan budur (en yeniden en eskiye doğru):
Gösterge
Tablosu
Gösterge Tablosu Gösterge Tablosu
Arama
Dizini
Buradaki sorun, bir kullanıcı ileri veya geri düğmelerini tıklattığında, yanlış sayfaya yönlendirilecek veya bir kez geri gitmek için birden çok kez tıklamaları gerekecektir. Bu, gidip tarihlerini kontrol etmeleri anlamsız olacaktır.
Şimdiye kadar sahip olduğum şey bu:
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);
}
}
});
Tüm yardımlar takdir
ediliyor , Şerefe.
updateHistoryişlevinize tarayıcı geçmişi öğeleri ekliyorsunuz . Şimdi updateHistory, 1, iki kez denilen almak olabilir Eğer Traveler'ı başlatılıyor yaparken ( window.Traveller = new Traveller();, constructor-> init-> send-> render-> updateHistory), sonra da tarafından redirectgelen clickEventListener. Ben test etmedim, sadece vahşi tahmin, bu yüzden bir cevap olarak değil bir yorum olarak ekleyerek.