Pertanyaan ini mirip dengan Lacak saat pengguna menekan tombol kembali di browser , tetapi tidak sama ... Saya punya solusi dan saya mempostingnya di sini untuk referensi dan umpan balik. Jika ada yang punya pilihan yang lebih baik, saya mendengarkan!
Situasinya adalah saya memiliki halaman dengan "edit di tempat", a la flickr. Yaitu ada DIV "klik di sini untuk menambahkan deskripsi", yang bila diklik berubah menjadi TEXTAREA dengan tombol Simpan dan Batal. Mengklik Simpan posting data ke server untuk memperbarui database dan menempatkan deskripsi baru di DIV sebagai pengganti TEXTAREA. Jika halaman di-refresh, deskripsi baru ditampilkan dari database dengan opsi "klik untuk mengedit". Hal-hal web 2.0 yang cukup standar hari ini.
Masalahnya adalah jika:
- halaman dimuat tanpa deskripsi
- deskripsi ditambahkan oleh pengguna
- halaman dinavigasi keluar dengan mengklik link
- pengguna mengklik tombol kembali
Kemudian yang ditampilkan (dari cache browser) adalah versi halaman tanpa DIV yang dimodifikasi secara dinamis berisi deskripsi baru.
Ini adalah masalah yang cukup besar karena pengguna berasumsi bahwa pembaruan mereka telah hilang dan tidak perlu memahami bahwa mereka perlu menyegarkan laman untuk melihat perubahan.
Jadi, pertanyaannya adalah: Bagaimana Anda bisa menandai halaman sebagai diubah setelah dimuat, dan kemudian mendeteksi ketika pengguna "kembali ke sana" dan memaksa penyegaran dalam situasi itu?
sumber
Jawaban:
Gunakan formulir tersembunyi. Data formulir disimpan (biasanya) di browser saat Anda memuat ulang atau menekan tombol kembali untuk kembali ke halaman. Hal berikut masuk ke halaman Anda (mungkin di dekat bagian bawah):
<form name="ignore_me"> <input type="hidden" id="page_is_dirty" name="page_is_dirty" value="0" /> </form>
Di javascript Anda, Anda memerlukan yang berikut ini:
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 yang mengendus formulir harus dieksekusi setelah html sepenuhnya diurai, tetapi Anda dapat meletakkan formulir dan js sebaris di bagian atas halaman (js detik) jika latensi pengguna menjadi masalah serius.
sumber
Berikut adalah solusi modern yang sangat mudah untuk masalah lama ini.
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 saat ini didukung oleh semua browser utama.
sumber
window.performance && window.performance.navigation.type
alih - alih hanyawindow.performance.navigation.TYPE_BACK_FORWARD
?).window.performance.navigation.TYPE_BACK_FORWARD
adalah konstanta yang selalu sama dengan 2. Jadi, ini hanya digunakan untuk perbandingan.performance.navigation
sudah usang dan disarankan untuk menggunakan developer.mozilla.org/en-US/docs/Web/API/…2
untuk klik tombol kembali. Hingga v70, kesalahan dikembalikan1
.Artikel ini menjelaskannya. Lihat kode di bawah ini: 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>
sumber
event.persisted
=false
, bahkan saat menekan dari tombol kembali. Anda harus menggunakanwindow.performance.navigation
atau PerformanceNavigationTiming untuk Chrome.Untuk peramban modern, ini sepertinya cara yang benar sekarang:
const perfEntries = performance.getEntriesByType('navigation'); if (perfEntries.length && perfEntries[0].type === 'back_forward') { console.log('User got here from Back or Forward button.'); }
Ini masih "Eksperimental" pada Jan 2020, tetapi tampaknya didukung dengan baik.
https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming
sumber
Seperti disebutkan di atas, saya telah menemukan solusi dan mempostingnya di sini untuk referensi dan umpan balik.
Langkah pertama dari solusi adalah menambahkan yang berikut ini ke halaman:
<!-- 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>
Isi dari
fresh.html
tidak penting, jadi berikut ini sudah cukup:<!-- fresh.html --> <HTML><BODY></BODY></HTML>
Ketika kode sisi klien memperbarui halaman, itu perlu menandai modifikasi sebagai berikut:
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
melakukan semua pekerjaan: Saat dimuat itu akan memanggilreload_stale_page
fungsi yang akan menyegarkan halaman jika perlu. Pertama kali dimuat (yaitu setelah modifikasi dilakukan,reload_stale_page
fungsi tidak akan melakukan apa pun.)<!-- stale.html --> <HTML><BODY> <SCRIPT type="text/javascript">window.parent.reload_stale_page();</SCRIPT> </BODY></HTML>
Dari pengujian (minimal) saya pada tahap ini, ini sepertinya berfungsi seperti yang diinginkan. Apakah saya melewatkan sesuatu?
sumber
Anda dapat menyelesaikannya menggunakan acara onbeforeunload :
window.onbeforeunload = function () { }
Memiliki fungsi event manager kosong onbeforeunload berarti halaman akan dibangun kembali setiap kali diakses. Javascript akan dijalankan ulang, skrip sisi server akan dijalankan kembali, halaman akan dibuat seolah-olah pengguna pertama kali membukanya, meskipun pengguna membuka halaman hanya dengan menekan tombol kembali atau maju .
Berikut adalah kode lengkap dari sebuah contoh:
<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>
Cobalah, keluar dari halaman ini lalu kembali menggunakan tombol "Kembali" atau "Maju" di browser Anda.
Ini berfungsi dengan baik di IE, FF dan Chrome.
Tentu saja Anda dapat melakukan apapun yang Anda inginkan di dalam fungsi myfun .
Info lebih lanjut: http://www.hunlock.com/blogs/Mastering_The_Back_Button_With_Javascript
sumber
Anda dapat menggunakan localStorage atau sessionStorage ( http://www.w3schools.com/html/html5_webstorage.asp ) untuk mengatur bendera (daripada menggunakan formulir tersembunyi).
sumber
Menggunakan halaman ini, terutama menggabungkan komentar oleh @sajith tentang jawaban oleh @Nick White dan halaman ini: 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(); } });
sumber
Ini versi jQuery. Saya mengalami keharusan untuk menggunakannya beberapa kali karena cara Safari desktop / seluler menangani cache saat pengguna menekan tombol kembali.
$(window).bind("pageshow", function(event) { if (event.originalEvent.persisted) { // Loading from cache } });
sumber
Saya mengalami masalah serupa hari ini dan saya menyelesaikannya dengan localStorage (di sini dengan sedikit 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'); } });
Si pada dasarnya:
Pada halaman 1, saat pengguna mengirimkan formulir, kami menetapkan nilai "langkah" di localStorage untuk menunjukkan langkah apa yang telah diambil pengguna. Pada saat yang sama, kami meluncurkan fungsi dengan waktu tunggu yang akan memeriksa apakah nilai ini telah diubah (misalnya 10 kali / detik).
Pada halaman 2, kami segera mengubah nilai tersebut.
Jadi jika pengguna menggunakan tombol kembali dan browser mengembalikan halaman 1 dalam keadaan yang sama persis seperti ketika kita meninggalkannya, fungsi checkSteps masih berjalan, dan dapat mendeteksi bahwa nilai di localStorage telah diubah (dan dapat mengambil tindakan yang sesuai. ). Setelah pemeriksaan ini memenuhi tujuannya, tidak perlu terus menjalankannya, jadi kami tidak lagi menggunakan setTimeout.
sumber