To pytanie jest podobne do opcji Śledź, kiedy użytkownik kliknie przycisk Wstecz w przeglądarce , ale nie to samo ... Mam rozwiązanie i zamieszczam je tutaj w celach informacyjnych i zwrotnych. Jeśli ktoś ma jakieś lepsze opcje, mam uszy!
Sytuacja jest taka, że mam stronę z "edycją w miejscu" a la flickr. To znaczy „kliknij tutaj, aby dodać opis” DIV, który po kliknięciu zamienia się w TEXTAREA z przyciskami Zapisz i Anuluj. Kliknięcie Zapisz powoduje wysłanie danych do serwera w celu aktualizacji bazy danych i umieszczenie nowego opisu w DIV w miejsce TEXTAREA. Jeśli strona zostanie odświeżona, nowy opis zostanie wyświetlony z bazy danych z opcją „kliknij, aby edytować”. Dość standardowe rzeczy w web 2.0 w dzisiejszych czasach.
Problem polega na tym, że jeśli:
- strona jest ładowana bez opisu
- opis jest dodawany przez użytkownika
- strona jest opuszczana przez kliknięcie łącza
- użytkownik klika przycisk Wstecz
Wówczas wyświetlana jest (z pamięci podręcznej przeglądarki) wersja strony bez dynamicznie modyfikowanego DIV zawierającego nowy opis.
Jest to dość duży problem, ponieważ użytkownik zakłada, że jego aktualizacja została utracona i niekoniecznie zrozumie, że musi odświeżyć stronę, aby zobaczyć zmiany.
A więc pytanie brzmi: jak oflagować stronę jako modyfikowaną po jej załadowaniu, a następnie wykryć, kiedy użytkownik „wraca do niej” i wymusić odświeżenie w takiej sytuacji?
źródło
Odpowiedzi:
Użyj ukrytego formularza. Dane formularzy są zachowywane (zazwyczaj) w przeglądarkach po ponownym załadowaniu lub naciśnięciu przycisku Wstecz w celu powrotu do strony. Następujące informacje znajdują się na Twojej stronie (prawdopodobnie u dołu):
<form name="ignore_me"> <input type="hidden" id="page_is_dirty" name="page_is_dirty" value="0" /> </form>
W swoim javascript będziesz potrzebować:
var dirty_bit = document.getElementById('page_is_dirty'); if (dirty_bit.value == '1') window.location.reload(); function mark_page_dirty() { dirty_bit.value = '1'; }
Js, który wykrywa formularz, musi zostać wykonany po całkowitym przeanalizowaniu kodu HTML, ale możesz umieścić zarówno formularz, jak i js na górze strony (sekunda js), jeśli opóźnienie użytkownika jest poważnym problemem.
źródło
Oto bardzo proste, nowoczesne rozwiązanie tego starego problemu.
if (window.performance && window.performance.navigation.type === window.performance.navigation.TYPE_BACK_FORWARD) { alert('Got here using the browser "Back" or "Forward" button.'); }
window.performance jest obecnie obsługiwane przez wszystkie główne przeglądarki.
źródło
window.performance && window.performance.navigation.type
zamiast tylkowindow.performance.navigation.TYPE_BACK_FORWARD
?).window.performance.navigation.TYPE_BACK_FORWARD
jest stałą, która jest zawsze równa 2. Jest więc używana tylko do porównania.performance.navigation
to, że jest przestarzały i sugeruje się, aby zamiast niego użyć developer.mozilla.org/en-US/docs/Web/API/ ...2
dla kliknięć przycisku wstecz. Aż do wersji 70 zwracał nieprawidłowo1
.Ten artykuł wyjaśnia to. Zobacz poniższy kod: http://www.webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/
<html> <head> <script> function pageShown(evt){ if (evt.persisted) { alert("pageshow event handler called. The page was just restored from the Page Cache (eg. From the Back button."); } else { alert("pageshow event handler called for the initial load. This is the same as the load event."); } } function pageHidden(evt){ if (evt.persisted) { alert("pagehide event handler called. The page was suspended and placed into the Page Cache."); } else { alert("pagehide event handler called for page destruction. This is the same as the unload event."); } } window.addEventListener("pageshow", pageShown, false); window.addEventListener("pagehide", pageHidden, false); </script> </head> <body> <a href="http://www.webkit.org/">Click for WebKit</a> </body> </html>
źródło
event.persisted
=false
, nawet po naciśnięciu przycisku Wstecz. Musisz użyćwindow.performance.navigation
lub PerformanceNavigationTiming dla Chrome.W przypadku nowoczesnych przeglądarek wydaje się to teraz właściwe:
const perfEntries = performance.getEntriesByType('navigation'); if (perfEntries.length && perfEntries[0].type === 'back_forward') { console.log('User got here from Back or Forward button.'); }
Jest to nadal „eksperymentalne” od stycznia 2020 r., Ale wydaje się, że jest dobrze obsługiwane.
https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming
źródło
Jak wspomniano powyżej, znalazłem rozwiązanie i zamieszczam je tutaj w celach informacyjnych i zwrotnych.
Pierwszym etapem rozwiązania jest dodanie do strony:
<!-- at the top of the content page --> <IFRAME id="page_is_fresh" src="fresh.html" style="display:none;"></IFRAME> <SCRIPT style="text/javascript"> function reload_stale_page() { location.reload(); } </SCRIPT>
Treść
fresh.html
nie jest ważna, więc wystarczy:<!-- fresh.html --> <HTML><BODY></BODY></HTML>
Gdy kod po stronie klienta aktualizuje stronę, musi oznaczyć modyfikację w następujący sposób:
function trigger_reload_if_user_clicks_back_button() { // "dis-arm" the reload stale page function so it doesn't fire // until the page is reloaded from the browser's cache window.reload_stale_page = function(){}; // change the IFRAME to point to a page that will reload the // page when it loads document.getElementById("page_is_fresh").src = "stale.html"; }
stale.html
wykonuje całą pracę: po załadowaniu wywołareload_stale_page
funkcję, która w razie potrzeby odświeży stronę. Gdy jest ładowany po raz pierwszy (tj. Po dokonaniu modyfikacjireload_stale_page
funkcja nic nie zrobi).<!-- stale.html --> <HTML><BODY> <SCRIPT type="text/javascript">window.parent.reload_stale_page();</SCRIPT> </BODY></HTML>
Z moich (minimalnych) testów na tym etapie wynika, że działa to zgodnie z oczekiwaniami. Czy coś przeoczyłem?
źródło
Możesz rozwiązać ten problem za pomocą zdarzenia onbeforeunload :
window.onbeforeunload = function () { }
Posiadanie pustej funkcji menedżera zdarzeń przed załadowaniem oznacza, że strona zostanie odbudowana za każdym razem, gdy zostanie uzyskana. Skrypty JavaScript zostaną ponownie uruchomione, skrypty po stronie serwera zostaną ponownie uruchomione, strona zostanie zbudowana tak, jakby użytkownik klikał ją po raz pierwszy, nawet jeśli użytkownik dostał się na stronę, naciskając przycisk Wstecz lub Dalej .
Oto pełny kod przykładu:
<html> <head> <title>onbeforeunload.html</title> <script> window.onbeforeunload = function () { } function myfun() { alert("The page has been refreshed."); } </script> <body onload="myfun()"> Hello World!<br> </body> </html>
Wypróbuj, opuść tę stronę, a następnie wróć za pomocą przycisków „Wstecz” lub „Dalej” w przeglądarce.
Działa dobrze w IE, FF i Chrome.
Oczywiście możesz robić, co chcesz, korzystając z funkcji myfun .
Więcej informacji: http://www.hunlock.com/blogs/Mastering_The_Back_Button_With_Javascript
źródło
Możesz użyć localStorage lub sessionStorage ( http://www.w3schools.com/html/html5_webstorage.asp ), aby ustawić flagę (zamiast używać ukrytego formularza).
źródło
Korzystanie z tej strony, w szczególności uwzględnienie komentarza @sajith na temat odpowiedzi @Nick White i tej strony: http://www.mrc-productivity.com/techblog/?p=1235
<form name="ignore_me" style="display:none"> <input type="text" id="reloadValue" name="reloadValue" value="" /> </form> $(function () { var date = new Date(); var time = date.getTime(); if ($("#reloadValue").val().length === 0) { $("#reloadValue").val(time); } else { $("#reloadValue").val(""); window.location.reload(); } });
źródło
Oto wersja jQuery. Kilkakrotnie musiałem go użyć ze względu na sposób, w jaki Safari na komputer / telefon obsługuje pamięć podręczną, gdy użytkownik naciśnie przycisk Wstecz.
$(window).bind("pageshow", function(event) { if (event.originalEvent.persisted) { // Loading from cache } });
źródło
Dziś napotkałem podobny problem i rozwiązałem go przy pomocy localStorage (tutaj z odrobiną jQuery):
$(function() { if ($('#page1').length) { // this code must only run on page 1 var checkSteps = function () { if (localStorage.getItem('steps') == 'step2') { // if we are here, we know that: // 1. the user is on page 1 // 2. he has been on page 2 // 3. this function is running, which means the user has submitted the form // 4. but steps == step2, which is impossible if the user has *just* submitted the form // therefore we know that he has come back, probably using the back button of his browser alert('oh hey, welcome back!'); } else { setTimeout(checkSteps, 100); } }; $('#form').on('submit', function (e) { e.preventDefault(); localStorage.setItem('steps', 'step1'); // if "step1", then we know the user has submitted the form checkOrderSteps(); // ... then do what you need to submit the form and load page 2 }); } if ($('#page2').length) { // this code must only run on page 2 localStorage.setItem('steps', 'step2'); } });
Zasadniczo:
Na stronie 1, gdy użytkownik przesyła formularz, ustawiamy wartość „steps” w localStorage, aby wskazać, jaki krok wykonał użytkownik. Jednocześnie uruchamiamy funkcję z limitem czasu, która sprawdzi, czy ta wartość została zmieniona (np. 10 razy / sekundę).
Na stronie 2 natychmiast zmieniamy wspomnianą wartość.
Jeśli więc użytkownik użyje przycisku Wstecz, a przeglądarka przywróci stronę 1 dokładnie w takim stanie, w jakim ją opuściliśmy, funkcja checkSteps nadal działa i jest w stanie wykryć, że wartość w localStorage została zmieniona (i może podjąć odpowiednią akcję ). Gdy to sprawdzenie spełni swoje zadanie, nie ma potrzeby kontynuowania go, więc po prostu nie używamy już setTimeout.
źródło