Я створив веб-додаток, який використовує методи history pushStateта replaceStateметоди для навігації по сторінках, а також оновлення історії.
Сам сценарій працює майже ідеально; він завантажить сторінки правильно та викине помилки на сторінці, коли їх потрібно буде кинути. Однак я помітив дивну проблему, коли pushStateв історію підштовхнуть декілька, дублюються записи (і замінять записи).
Наприклад, скажімо, я роблю наступне (по порядку):
Завантажте index.php (історія буде: індекс)
Перейдіть до profile.php (історія буде: Профіль, індекс)
Перейдіть до search.php (історія буде: Пошук, Пошук, Індекс)
Перейдіть до dashboard.php
І нарешті, ось що з’явиться в моїй історії (в порядку найсвіжішого до найдавнішого):
Індекс пошуку на приладовій панелі
приладової
панелі Індекс
пошуку
Проблема з цим полягає в тому, що коли користувач натискає кнопки вперед або назад, він або перенаправляється на неправильну сторінку, або доведеться натискати кілька разів, щоб один раз повернутися назад. Це, і не буде сенсу, якщо вони завітають і перевірять свою історію.
Ось що я маю досі:
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);
}
}
});
Всяка допомога вдячна,
привіт.
updateHistoryфункцію. Тепер, updateHistoryякщо ви ініціалізуєте Traveller ( window.Traveller = new Traveller();, constructor-> init-> send-> render-> updateHistory), redirectвам clickдзвонять двічі , потім також від EventListener. Я не перевіряв його, просто дикі здогадки, тому додаю це як коментар, а не відповідь.