history.replaceState () örneği?


127

Herhangi biri history.replaceState için çalışan bir örnek verebilir mi? Bu nedir w3.org diyor ki:

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

Oturum geçmişindeki mevcut girişi, verilen verilere, başlığa ve sağlanmışsa ve boş değilse URL'ye sahip olacak şekilde günceller.

Güncelleme:

Bu mükemmel çalışıyor:

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

URL değişiyor, ancak başlık değişmiyor. Bu bir hata mı yoksa bir şey mi kaçırıyorum? En son Chrome'da test edilmiştir.


3
Genelde JavaScript soruları için eklenti kitaplıkları göndermem, ancak bu durumda bir istisna yapacağım. History.js kütüphanesi küçük pul olduğunu modern tarayıcılarda Tarih API tuhaf aksaklığı bir sürü kadar temizler. Hatta eski IE sürümleri için isteğe bağlı destek sağlar.
Sivri

2

@Pointy history.js harika çalışıyor. Sorumdaki kodu güncelledim. Hayır, benim sorunum, tarayıcı geri düğmesiyle önceki sayfaya geri
dönemiyorum

3
Göre Mozilla , titleparametre aslında kullanılmaz.
Rocket Hazmat

3
Soru bir replaceStateörnek istediği için ilk cevap gerçekten kabul edilen cevap olmamalıdır ve kabul edilen cevap hiçbir şekilde bir replaceStateörnek değildir.
CorayThan

Yanıtlar:


68

Aslında bu, 2 yıldır kasıtlı olmasına rağmen bir hatadır. Sorun, bazı belirsiz özelliklerde ve ne zaman document.titleve ne zaman geri / ileri söz konusu olduğunun karmaşıklığında yatıyor .

Webkit ve Mozilla'daki hata referansına bakın . Ayrıca History API'nin tanıtımı üzerine Opera , title parametresini kullanmadığını ve muhtemelen hala kullanmadığını söyledi .

Şu anda pushState ve replaceState'in 2. argümanı - geçmiş girişinin başlığı - Opera'nın uygulamasında kullanılmamaktadır, ancak bir gün olabilir.

Potansiyel çözüm

Gördüğüm tek yol, başlık öğesini değiştirmek ve bunun yerine pushState kullanmak:

document.getElementsByTagName('title')[0].innerHTML = 'bar';
window.history.pushState( {} , 'bar', '/bar' );

Jquery kullanıcıları için .. $ ("title"). Html (_title);
suraj jain

3
bu, bunu nasıl uyguladığınıza bağlı olarak kullanıcıların geri düğmesini "çift tıklaması" gerekmesine neden olabilir. Daha basit bir çözüm, kullanmaya devam etmek replaceState()ve belge başlığını manuel olarak ayarlamak olabilirdocument.title = "title"
newshorts

38

İşte minimal, uydurma bir örnek.

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

Daha fazlası var replaceState()ama onunla yapmak istediğiniz şeyin tam olarak ne olduğunu bilmiyorum.


2
url değişiyor, ancak başlık değişmiyor .. en son chrome ile test edildi @trott
Serjas

6
@Serjas içindeki titleparametre, bildiğim kadarıyla replaceState(), tüm tarayıcılarda göz ardı edilir.
Trott

10

history.pushStategeçerli sayfa durumunu geçmiş yığınına aktarır ve adres çubuğundaki URL'yi değiştirir. Yani geri döndüğünüzde o durum (geçtiğiniz nesne) size geri dönüyor.

Şu anda tüm yaptığı bu. Yeni sayfanın görüntülenmesi veya sayfa başlığının değiştirilmesi gibi diğer sayfa eylemleri sizin tarafınızdan yapılmalıdır.

Bağladığınız W3C özelliği yalnızca bir taslaktır ve tarayıcı bunu farklı şekilde uygulayabilir. Örneğin Firefox , titleparametreyi tamamen yok sayar .

İşte pushStateweb sitemde kullandığım basit bir örnek .

(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));

29
Kabul edilen yanıt neden "replaceState" yerine "pushState" i açıklıyor?
Giwrgos Tsopanoglou

1
@GiwrgosTsopanoglou: Bunu bir yıl önce cevapladım, bu yüzden neden olduğundan emin değilim: -P Neyse, replaceStatemevcut sayfa durumunu değiştirir. Mevcut sayfa durumunun durum nesnesini ve URL'sini değiştirmenize izin verir .
Rocket Hazmat

2
ReplaceState hakkında bilgi arıyordum ve sonunda pushState: P
Giwrgos Tsopanoglou

6

Örneğe bakınız

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);

ve arama location.hash;



2

Göre MDN Geçmişi doc
İkinci argümanın şimdilik değil gelecek için kullanıldığı açıkça söyleniyor. İkinci argümanın web sayfası başlığıyla ilgili olduğu konusunda haklısınız, ancak şu anda tüm büyük tarayıcılar tarafından görmezden geliniyor.

Firefox şu anda bu parametreyi görmezden geliyor, ancak gelecekte kullanabilecek. Buraya boş dizeyi geçirmek, yöntemde gelecekteki değişikliklere karşı güvenli olmalıdır. Alternatif olarak, taşındığınız eyalet için kısa bir başlık iletebilirsiniz.


İkinci argüman yok değil web sayfanın başlığı bakın - Bağlı olduğu MDN doc diyor "kısa pas devlet için başlık Sen hareket meydana getirmektedir." . Bu, W3C geçmiş arabirim belgelerinde "Verilen veriyi verilen başlıkla oturum geçmişine aktarır " ifadesine uygundur . Bu cümledeki veriler durum verileridir, dolayısıyla başlık yine duruma (verilere) atıfta bulunur.
Stephen P

1

@ Sev'in cevabına gerçekten cevap vermek istedim.

Sev haklı, içinde bir böcek var window.history.replaceState

Bunu düzeltmek için yapıcıyı yeniden yazarak başlığı manuel olarak ayarlayın.

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);
}

2
Bunu yapma. Varsayılan işlevlerin üzerine yazmak gerçekten kötü bir stil
René Roth

3
Bu hatanın düzeltilmesi gerektiğinde başka ne önerirsiniz?
Glenn Plas

@GlennPlas react repo'suna karşı bir PR
açıyor

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.