Bisakah Anda menggunakan navigasi hash tanpa memengaruhi riwayat?

100

Saya khawatir ini mungkin tidak mungkin, tetapi adakah cara untuk mengubah nilai hash URL tanpa meninggalkan entri di riwayat browser dan tanpa memuat ulang ? Atau melakukan yang setara?

Sejauh spesifikasinya, saya sedang mengembangkan beberapa navigasi hash dasar di sepanjang baris:

//hash nav -- works with js-tabs
var getHash = window.location.hash;
var hashPref = "tab-";
function useHash(newHash) {
    //set js-tab according to hash
    newHash = newHash.replace('#'+hashPref, '');
    $("#tabs li a[href='"+ newHash +"']").click();
}
function setHash(newHash) {
    //set hash according to js-tab
    window.location.hash = hashPref + newHash;

    //THIS IS WHERE I would like to REPLACE the location.hash
    //without a history entry

}
    // ... a lot of irrelavent tabs js and then....

    //make tabs work
    $("#tabs.js-tabs a").live("click", function() {
        var showMe = $(this).attr("href");
        $(showMe).show();
        setHash(showMe);
        return false;
    });
    //hash nav on ready .. if hash exists, execute
    if ( getHash ){
        useHash(getHash);
    }

Menggunakan jQuery, tentu saja. Idenya adalah bahwa dalam contoh khusus ini 1) membuat pengguna kembali ke setiap perubahan tab dapat secara efektif 'memecah tombol kembali' dengan menumpuk referensi yang tidak perlu, dan 2) tidak mempertahankan tab mana yang saat ini mereka aktifkan jika mereka menekan segarkan gangguan.


sumber
Mengapa Anda ingin mengubah hash jika Anda tidak ingin melacak riwayat? : |
Ionuț Staicu
10
Karena saat refresh, akan lebih baik untuk menampilkan pengguna dengan tab tempat mereka berada, tetapi karena mereka mungkin bolak-balik di antara tab, itu akan mengisi riwayat mereka dengan entri yang tidak perlu, membuat tombol kembali sebenarnya kurang berguna. Ini hanyalah sebuah contoh, meskipun - bisa saja kapan saja Anda perlu menyimpan status sementara tetapi tidak ingin bergantung pada cookie atau mengisi file temp pengguna dengannya. Saat Anda menyegarkan, konten js adalah seperti yang Anda tinggalkan - Anda belum meninggalkan halaman, dan ini bukan titik lompat atau halaman psuedo, jadi entri riwayat hanya dapat mengganggu navigasi standar.

Jawaban:

95

location.replace("#hash_value_here");berfungsi dengan baik untuk saya sampai saya menemukan bahwa itu tidak berfungsi di iOS Chrome. Dalam hal ini, gunakan:

history.replaceState(undefined, undefined, "#hash_value")

history.replaceState () beroperasi persis seperti history.pushState () kecuali bahwa replaceState () memodifikasi entri riwayat saat ini daripada membuat yang baru.

Ingatlah untuk tetap mempertahankan #atau bagian terakhir url akan diubah.

Lucia
sumber
3
Benar-benar cara terbaik untuk menggunakan peramban modern; menyadari dukungan parsial manajemen sejarah sesi memiliki sekalipun.
Matt
Saya bingung bagaimana cara menggunakan ini. Haruskah saya tetap menggunakan window.location.hash = 'my-hash';diikuti oleh history.replaceState(undefined, undefined, "#my-hash")?
Bram Vanroy
2
@BramVanroy Tidak, menggunakan yang terakhir sudah cukup.
Lucia
2
Kecuali Anda menggunakan: pemilih target ... maka fungsi riwayat tidak berguna, karena bagian dari spesifikasi (interaksi css dengan operasi riwayat) tampaknya tidak ditentukan saat ini, dan gaya tidak dihitung ulang pada riwayat yang diganti oleh sebagian besar / semua browser.
morphles
@Luxiyalu, Bagaimana history.replaceStateberbeda dari location.replace?
Pacerier
99
location.replace("#hash_value_here"); 

Di atas tampaknya melakukan apa yang Anda cari.

Matt
sumber
4
Ini dia. Dan jika Anda memiliki segmen uri, location.replace (window.location + "#hash") akan menyimpannya.
tedders
7
Kedua metode ini, lebih bersih, berharap itu ditandai sebagai jawaban yang benar.
joeellis
14
window.location.replace(('' + window.location).split('#')[0] + '#' + hash);untuk hanya memperbarui hash
johnstorm
1
Saya mengujinya di Chrome 30 pada Windows 8, jika saya membuka Riwayat Chrome dan memilih "Lainnya dari situs ini" di bawah url pengujian saya, saya dapat melihat semua hash yang ditambahkan dengan metode ini.
Alex Vang
1
Berhati-hatilah bahwa location.replace ('# hash_value_here') hanya mengubah fragmen hash dan bukan jalurnya, sehingga tidak memicu pemuatan halaman .... Kecuali jika dokumen berisi tag dasar: <base href ="http://example.com/" /> Jika memang berisi tag dasar , maka ketika Anda menggunakan metode ganti dengan hanya sebuah awalan "#hash_value_here"itu sebenarnya akan seperti jika Anda mengatakan `location.replace (' example.com/#hash_value_here' ). Ini tampak jelas ketika Anda membacanya di sini, tetapi menjadi masalah ketika Anda berada di halaman dengan fragmen jalur dan tidak menyadari bahwa basis telah ditetapkan.
Tyler Kasten
6

Sunting: Sudah beberapa tahun sekarang, dan browser telah berkembang.

@ Luxiyalu ini jawabannya adalah cara untuk pergi

- Jawaban Lama -

Saya juga berpikir itu tidak mungkin (saat ini). Tetapi mengapa Anda perlu mengubah nilai hash jika Anda tidak akan menggunakannya?

Saya yakin alasan utama mengapa kami menggunakan nilai hash sebagai pemrogram adalah untuk membiarkan pengguna menandai halaman kami, atau untuk menyimpan status dalam riwayat browser. Jika Anda tidak ingin melakukan semua ini, simpan saja status dalam variabel, dan kerjakan dari sana.

Saya pikir alasan menggunakan hash adalah untuk bekerja dengan nilai yang di luar kendali kami. Jika Anda tidak membutuhkannya, maka itu mungkin berarti Anda memiliki segalanya di bawah kendali Anda, jadi simpan saja status dalam variabel dan kerjakan dengannya. (Saya suka mengulang sendiri)

Saya harap ini membantu Anda. Mungkin ada solusi yang lebih mudah untuk masalah Anda.

UPDATE: Bagaimana dengan ini:

  1. Siapkan hash pertama, dan pastikan hash itu disimpan di riwayat browser.
  2. Ketika tab baru dipilih, lakukan window.history.back(1), itu akan membuat riwayat kembali dari hash init pertama Anda.
  3. Sekarang Anda mengatur hash baru, oleh karena itu tab hanya akan membuat satu entri dalam riwayat.

Anda mungkin harus menggunakan beberapa tanda, untuk mengetahui apakah entri saat ini dapat "dihapus" dengan kembali, atau jika Anda melewatkan langkah pertama. Dan untuk memastikan, bahwa metode pemuatan untuk "hash" tidak dijalankan, saat Anda memaksakan history.back.

guzart
sumber
Sangat mungkin ada sesuatu yang mendasar yang saya lewatkan (kelelahan adalah alasan yang bagus, saya akan pergi dengan itu) tetapi apakah Anda mengatakan saya dapat menetapkan variabel yang akan mempertahankan nilai yang berubah saat memuat ulang? Selain dengan cookie? (Cookies tampaknya berlebihan, entah bagaimana ..) Mungkin itu yang tidak jelas. Saya akan menggunakan nilai hash - terutama saat reload. Terima kasih telah menanggapi!
Untuk memperjelas klarifikasi saya: jika pengguna menekan muat ulang. Itulah gunanya hash. Saya masih mencoba untuk menghindari memuat ulang dalam penggunaan normal mereka (mengubah / mengklik tab).
Oke, jadi Anda akan menggunakan beberapa nilai untuk info setelah memuat ulang. Sayangnya, nilai hash akan diambil oleh beberapa riwayat browser. Maaf untuk mengatakan ini, tetapi dari exp saya, cookie adalah taruhan terbaik Anda. Jika Anda menginginkan sesuatu yang tidak dideteksi oleh riwayat browser, tetapi dipertahankan setelah memuat ulang, sayangnya, cookie. Jika pengguna mengklik link, maka Anda dapat mengatur link menjadi query ( ?mystate=greatness), meskipun tidak perlu ajax, Anda dapat menyimpan info untuk dibaca javascript saat menginisialisasi permintaan.
guzart
Ya, hash adalah untuk menyimpan info pengguna setelah menekan muat ulang, tetapi masalah untuk situasi Anda, adalah bahwa beberapa browser akan menyimpan perubahan tersebut dalam riwayat, begitulah cara kerjanya ... :(
guzart
Ya, menurut Anda Anda benar. Ah baiklah. (Ingin sekali terbukti salah dengan metode lain atau sesuatu.)
-1

Anda selalu dapat membuat event listener untuk menangkap event click di hyperlink dan dalam fungsi callback put e.preventDefault (), yang akan mencegah browser memasukkannya ke dalam sejarah.

Ayman Farhat
sumber