(Catatan: Sesuai umpan balik Sharky, saya telah menyertakan kode untuk mendeteksi backspaces)
Jadi, saya sering melihat pertanyaan-pertanyaan ini di SO, dan baru-baru ini mengalami masalah dalam mengontrol fungsi tombol kembali sendiri. Setelah beberapa hari mencari solusi terbaik untuk aplikasi saya (Satu Halaman dengan Navigasi Hash), saya telah membuat sistem yang sederhana, lintas peramban, tanpa perpustakaan untuk mendeteksi tombol kembali.
Kebanyakan orang merekomendasikan untuk menggunakan:
window.onhashchange = function() {
//blah blah blah
}
Namun, fungsi ini juga akan dipanggil ketika pengguna menggunakan elemen dalam halaman yang mengubah hash lokasi. Bukan pengalaman pengguna terbaik ketika pengguna Anda mengklik dan halaman berjalan mundur atau maju.
Untuk memberi Anda garis besar umum sistem saya, saya mengisi array dengan hash sebelumnya saat pengguna saya bergerak melalui antarmuka. Itu terlihat seperti ini:
function updateHistory(curr) {
window.location.lasthash.push(window.location.hash);
window.location.hash = curr;
}
Cukup lurus ke depan. Saya melakukan ini untuk memastikan dukungan lintas-browser, serta dukungan untuk browser yang lebih lama. Cukup sampaikan hash baru ke fungsi, dan itu akan menyimpannya untuk Anda dan kemudian mengubah hash (yang kemudian dimasukkan ke dalam sejarah browser).
Saya juga memanfaatkan tombol kembali di dalam halaman yang menggerakkan pengguna di antara halaman menggunakan lasthash
array. Ini terlihat seperti ini:
function goBack() {
window.location.hash = window.location.lasthash[window.location.lasthash.length-1];
//blah blah blah
window.location.lasthash.pop();
}
Jadi ini akan memindahkan pengguna kembali ke hash terakhir, dan menghapus hash terakhir dari array (saya tidak punya tombol maju sekarang).
Begitu. Bagaimana cara mendeteksi apakah pengguna telah menggunakan tombol kembali di-halaman saya, atau tombol browser?
Pada awalnya saya melihat window.onbeforeunload
, tetapi tidak berhasil - itu hanya disebut jika pengguna akan mengubah halaman. Ini tidak terjadi dalam aplikasi satu halaman menggunakan navigasi hash.
Jadi, setelah beberapa penggalian lagi, saya melihat rekomendasi untuk mencoba mengatur variabel flag. Masalah dengan ini dalam kasus saya, adalah bahwa saya akan mencoba untuk mengaturnya, tetapi karena semuanya asinkron, itu tidak akan selalu diatur dalam waktu untuk pernyataan if dalam perubahan hash. .onMouseDown
tidak selalu dipanggil klik, dan menambahkannya ke onclick tidak akan pernah memicunya cukup cepat.
Ini adalah ketika saya mulai melihat perbedaan antara document
, dan window
. Solusi terakhir saya adalah mengatur flag menggunakan document.onmouseover
, dan menonaktifkannya menggunakan document.onmouseleave
.
Yang terjadi adalah ketika mouse pengguna berada di dalam area dokumen (baca: halaman yang diberikan, tetapi tidak termasuk bingkai browser), boolean saya disetel ke true
. Segera setelah mouse meninggalkan area dokumen, boolean membalik ke false
.
Dengan cara ini, saya dapat mengubah window.onhashchange
ke:
window.onhashchange = function() {
if (window.innerDocClick) {
window.innerDocClick = false;
} else {
if (window.location.hash != '#undefined') {
goBack();
} else {
history.pushState("", document.title, window.location.pathname);
location.reload();
}
}
}
Anda akan mencatat cek untuk #undefined
. Ini karena jika tidak ada riwayat yang tersedia di array saya, itu kembali undefined
. Saya menggunakan ini untuk bertanya kepada pengguna apakah mereka ingin pergi menggunakan window.onbeforeunload
acara.
Jadi, singkatnya, dan untuk orang-orang yang tidak perlu menggunakan tombol kembali di-halaman atau array untuk menyimpan sejarah:
document.onmouseover = function() {
//User's mouse is inside the page.
window.innerDocClick = true;
}
document.onmouseleave = function() {
//User's mouse has left the page.
window.innerDocClick = false;
}
window.onhashchange = function() {
if (window.innerDocClick) {
//Your own in-page mechanism triggered the hash change
} else {
//Browser back button was clicked
}
}
Dan begitulah. sederhana, tiga bagian cara untuk mendeteksi penggunaan tombol kembali vs elemen dalam halaman sehubungan dengan navigasi hash.
EDIT:
Untuk memastikan bahwa pengguna tidak menggunakan backspace untuk memicu acara kembali, Anda juga dapat memasukkan yang berikut (Terima kasih kepada @thetoolman pada Pertanyaan ini ):
$(function(){
/*
* this swallows backspace keys on any non-input element.
* stops backspace -> back
*/
var rx = /INPUT|SELECT|TEXTAREA/i;
$(document).bind("keydown keypress", function(e){
if( e.which == 8 ){ // 8 == backspace
if(!rx.test(e.target.tagName) || e.target.disabled || e.target.readOnly ){
e.preventDefault();
}
}
});
});