contoh history.replaceState ()?

127

Adakah yang bisa memberikan contoh yang baik untuk history.replaceState? Inilah yang dikatakan w3.org :

history . replaceState(data, title [, url ] )

Memperbarui entri saat ini dalam riwayat sesi untuk memiliki data, judul, dan, jika disediakan dan bukan null, URL.

Memperbarui:

Ini bekerja dengan sempurna:

history.replaceState( {} , 'foo', '/foo' );

Url berubah, tetapi judul tidak berubah. Apakah itu bug atau saya melewatkan sesuatu? Diuji pada Chrome terbaru.

Serja
sumber
3
Saya biasanya tidak mendorong pustaka add-on untuk pertanyaan JavaScript, tetapi dalam hal ini saya akan membuat pengecualian. The History.js perpustakaan adalah shim kecil yang membersihkan up banyak perilaku aneh dalam API Sejarah di seluruh browser modern. Bahkan menyediakan dukungan opsional untuk versi lama IE.
Runcing
2
MDN memiliki tulisan yang cukup bagus tentang Memanipulasi riwayat browser
sachleen
@Pointy history.js berfungsi dengan baik. Saya telah memperbarui kode dalam pertanyaan saya. Tidak masalah saya adalah saya tidak bisa kembali ke halaman sebelumnya dengan tombol kembali browser
Serjas
3
Menurut Mozilla , titleparameternya sebenarnya tidak digunakan.
Rocket Hazmat
3
Jawaban pertama benar-benar tidak boleh menjadi jawaban yang diterima, mengingat pertanyaannya menanyakan replaceStatecontoh, dan jawaban yang diterima sama sekali bukan replaceStatecontoh.
CorayThan

Jawaban:

68

Memang ini bug, meski disengaja selama 2 tahun sekarang. Masalahnya terletak pada beberapa spesifikasi yang tidak jelas dan kompleksitas ketika document.titledan mundur / maju terlibat.

Lihat referensi bug di Webkit dan Mozilla . Juga Opera pada pengantar History API mengatakan itu tidak menggunakan parameter judul dan mungkin masih tidak.

Saat ini argumen ke-2 pushState dan replaceState - judul entri riwayat - tidak digunakan dalam implementasi Opera, tetapi mungkin satu hari.

Solusi potensial

Satu-satunya cara yang saya lihat adalah mengubah elemen judul dan menggunakan pushState sebagai gantinya:

document.getElementsByTagName('title')[0].innerHTML = 'bar';
window.history.pushState( {} , 'bar', '/bar' );
Sev
sumber
Untuk pengguna jquery .. coba $ ("title"). Html (_title);
suraj jain
3
ini dapat mengakibatkan pengguna perlu "mengklik dua kali" tombol kembali tergantung pada bagaimana Anda menerapkannya. Solusi yang lebih sederhana adalah tetap menggunakan replaceState()dan cukup mengatur judul dokumen secara manualdocument.title = "title"
newshorts
38

Ini adalah contoh minimal yang dibuat-buat.

console.log( window.location.href );  // whatever your current location href is
window.history.replaceState( {} , 'foo', '/foo' );
console.log( window.location.href );  // oh, hey, it replaced the path with /foo

Ada lagi yang harus replaceState()saya lakukan tetapi saya tidak tahu apa sebenarnya yang ingin Anda lakukan dengannya.

Trott
sumber
2
url berubah, tetapi judul tidak berubah .. diuji dengan chrome @trott terbaru
Serjas
6
@ Serjas titleParameter di replaceState()adalah, sepengetahuan saya, diabaikan di semua browser.
Trott
10

history.pushStatemendorong status halaman saat ini ke tumpukan riwayat, dan mengubah URL di bilah alamat. Jadi, ketika Anda kembali, keadaan itu (objek yang Anda lewati) dikembalikan kepada Anda.

Saat ini, hanya itu yang dilakukannya. Tindakan halaman lainnya, seperti menampilkan halaman baru atau mengubah judul halaman, harus dilakukan oleh Anda.

W3C spec yang Anda tautkan hanyalah konsep, dan browser dapat menerapkannya secara berbeda. Firefox , misalnya, mengabaikan titleparameter sepenuhnya.

Berikut adalah contoh sederhana pushStateyang saya gunakan di situs web saya.

(function($){
    // Use AJAX to load the page, and change the title
    function loadPage(sel, p){
        $(sel).load(p + ' #content', function(){
            document.title = $('#pageData').data('title');
        });
    }

    // When a link is clicked, use AJAX to load that page
    // but use pushState to change the URL bar
    $(document).on('click', 'a', function(e){
        e.preventDefault();
        history.pushState({page: this.href}, '', this.href);
        loadPage('#frontPage', this.href);
    });

    // This event is triggered when you visit a page in the history
    // like when yu push the "back" button
    $(window).on('popstate', function(e){
        loadPage('#frontPage', location.pathname);
        console.log(e.originalEvent.state);
    });
}(jQuery));
Roket Hazmat
sumber
29
Mengapa jawaban yang diterima menjelaskan "pushState" alih-alih "replaceState"?
Giwrgos Tsopanoglou
1
@GiwrgosTsopanoglou: Saya menjawab ini setahun yang lalu, jadi saya tidak yakin mengapa :-P Bagaimanapun, replaceStatemengubah keadaan halaman saat ini. Ini memungkinkan Anda mengubah objek negara dan URL dari kondisi halaman saat ini .
Rocket Hazmat
2
Hanya aneh bahwa saya mencari informasi tentang replaceState dan saya akhirnya membaca tentang pushState: P
Giwrgos Tsopanoglou
6

lihat contohnya

window.history.replaceState({
    foo: 'bar'
}, 'Nice URL Title', '/nice_url');

window.onpopstate = function (e) {
    if (typeof e.state == "object" && e.state.foo == "bar") {
        alert("Blah blah blah");
    }
};

window.history.go(-1);

dan pencarian location.hash;

avalkab
sumber
2

Menurut dokumen MDN History
Ada jelas mengatakan bahwa argumen kedua untuk masa depan digunakan bukan untuk saat ini. Anda benar bahwa argumen kedua berhubungan dengan judul halaman web tetapi saat ini diabaikan oleh semua browser utama.

Firefox saat ini mengabaikan parameter ini, meskipun mungkin menggunakannya di masa depan. Melewati string kosong di sini harus aman terhadap perubahan metode di masa mendatang. Atau, Anda bisa memberikan judul pendek untuk status yang Anda pindahkan.

Munir Khakhi
sumber
Argumen kedua tidak tidak merujuk pada judul halaman web - doc MDN yang Anda terhubung mengatakan "lulus singkat judul untuk negara yang Anda bergerak." . Ini setuju dengan dokumentasi antarmuka sejarah W3C yang mengatakan "Dorong data yang diberikan ke riwayat sesi, dengan judul yang diberikan," . Data dalam frasa itu adalah data status , jadi sekali lagi judulnya mengacu pada status (data).
Stephen P
1

Saya benar-benar ingin menanggapi jawaban @ Sev.

Sev benar, ada bug di dalamnya window.history.replaceState

Untuk memperbaiki ini cukup menulis ulang konstruktor untuk mengatur judul secara manual.

var replaceState_tmp = window.history.replaceState.constructor;
window.history.replaceState.constructor = function(obj, title, url){
    var title_ = document.getElementsByTagName('title')[0];
    if(title_ != undefined){
        title_.innerHTML = title;
    }else{
        var title__ = document.createElement('title');
        title__.innerHTML = title;
        var head_ = document.getElementsByTagName('head')[0];
        if(head_ != undefined){
            head_.appendChild(title__);
        }else{
            var head__ = document.createElement('head');
            document.documentElement.appendChild(head__);
            head__.appendChild(title__);
        }
    }
    replaceState_tmp(obj,title, url);
}
THE AMAZING
sumber
2
Jangan lakukan itu. Menimpa fungsi standar adalah gaya yang benar-benar buruk
René Roth
3
apa lagi yang Anda sarankan ketika Anda perlu memperbaiki bug ini?
Glenn Plas
@ GlennPlas membuka PR terhadap repo reaksi :)
zero_cool
0

Misalkan https://www.mozilla.org/foo.html menjalankan JavaScript berikut:

const stateObj = { foo: 'bar' };

history.pushState(stateObj, '', 'bar.html');

Ini akan menyebabkan bilah URL untuk menampilkan https://www.mozilla.org/bar2.html , tetapi tidak akan menyebabkan peramban memuat bar2.html atau bahkan memeriksa apakah bar2.html ada.

abu
sumber