javascript - problem z przyciskiem wstecz w History API i History.js
Ładuję stronę za pomocą Ajax. Gdy użytkownik kliknie link, strona jest ładowana przez AJAX pomyślnie, ale gdy użytkownik kliknie przycisk wstecz, strona ponownie ładuje stronę początkową. Tak więc scenariusz wygląda tak.
- Załaduj stronę początkową (index.php)
- Użytkownik klika w link
- Strona ładuje się pomyślnie
- Kliknij przycisk Wstecz
- Początkowa strona jest teraz wyświetlana dwa razy.
Oto oznaczenie.
$(function() {
// Prepare
var History = window.History; // Note: We are using a capital H instead of a lower h
if (!History.enabled) {
// History.js is disabled for this browser.
// This is because we can optionally choose to support HTML4 browsers or not.
return false;
}
// Bind to StateChange Event
History.Adapter.bind(window, 'statechange', function() { // Note: We are using statechange instead of popstate
var State = History.getState();
$('#content').load(State.url);
});
$('a').click(function(evt) {
evt.preventDefault();
History.pushState(null, $(this).text(), $(this).attr('href'));
alert(State.url)
});
});
To jest znacznik
<div id="wrap">
<a href="page1.html">Page 1</a>
</div>
<div id="content">
<p>Content within this box is replaced with content from
supporting pages using javascript and AJAX.</p>
</div>
Jeśli nadal nie rozumiesz mojego pytania ani scenariusza
Oto pełny scenariusz. Strona początkowa
Kiedy użytkownik kliknie link, wybrana strona zostanie pomyślnie załadowana
Kiedy klikam przycisk wstecz, początkowa strona jest teraz podwójna
Jak widać, link „Page1” jest podwójny. Czy to problem z przeglądarką? Czy może moje rozumienie API historii coś pomija lub jest niepełne? Jakie jest możliwe rozwiązanie tego problemu?
Odpowiedź #1
Jeśli zbudujesz swoją stronę tak, aby korzystała z podobnego szablonu zarówno dla stron głównych, jak i stron z treścią, możesz użyć składni selektora kontenera dla jquery.load:
// See: http://api.jquery.com/load/
$('#result').load('ajax/test.html #container');
Co w Twoim przypadku skutkowałoby:
$('#content').load(State.url + ' #content');
Będzie to miało dodatkową zaletę, że strony z adresami URL treści będą również bezpośrednio dostępne, bez dodawania zbyt wielu sztuczek.
Odpowiedź #2
To może się zdarzyć, ponieważ gdy cofasz nawigację, wywołane zostanie zdarzenie 'statechange', a w twoim wywołaniu zwrotnym ładujesz zawartość tej strony za pomocą podanego adresu URL: $ ('#content').load(State.url);, więc gdy na przykład cofasz się do adresu URL /, zostanie załadowana zawartość tej strony indeksu i umieszczona wewnątrz twojego kontenera, więc twój markup w rzeczywistości będzie wyglądał tak:
<div id="wrap">
<a href="page1.html">Page 1</a>
</div>
<div id="content">
<div id="wrap">
<a href="page1.html">Page 1</a>
</div>
<div id="content">
<p>Content within this box is replaced with content from
supporting pages using javascript and AJAX.</p>
</div>
</div>
Istnieje kilka sposobów rozwiązania tego problemu - najprostszy polega na wykryciu, czy użytkownik przeszedł na stronę początkową i nie ładowaniu tej strony przez AJAX, lecz wstawieniu wcześniej zdefiniowanej zawartości. Można również wykryć po stronie serwera, czy żądanie zostało wykonane za pomocą AJAX, a następnie zwrócić tylko zawartość potrzebną do aktualizacji strony (co w twoim przypadku może być <p>Zawartość w tym polu jest zastępowana zawartością z innych stron przy użyciu JavaScript i AJAX.</p>)


