JavaScript kullanarak yeni sayfayı yüklemeden tarayıcıdaki URL'yi değiştirme


297

Geçerli sayfada bazı etkileri olabilecek ancak tarayıcıdaki URL'yi de değiştirecek bir JavaScript işlemine nasıl sahip olabilirim, böylece kullanıcı yeniden yüklemeye veya yer işaretine çarparsa yeni URL kullanılır?

Geri düğmesinin orijinal URL'yi yeniden yüklemesi de iyi olur.

URL'de JavaScript durumunu kaydetmeye çalışıyorum.


1
Bu çok hoş olurdu. Tabii ki aynı alandaki değişikliklerle sınırlı olacaktı. Ancak, yolun bazı istemci tarafı kontrolü (ve sadece karma değil) artık sayfa yeniden yüklemelerinin birçok uygulama için bir tür "son çare" olduğu mantıklı bir adımdır.
harpo

1
Bir "tür" iyi kullanımı pushState:for(i=1;i<50;i++){var txt="..................................................";txt=txt.slice(0,i)+"HTML5"+txt.slice(i,txt.length);history.pushState({}, "html5", txt);}
Derek 朕 會 功夫

eylem bu etkisi örneği: dujour.com
Ben

2
Bu efekt örneği: facebook.com (Görüntüleri ışık

bu iyi bir soru. Ancak, bu soru bugün bu şekilde sorulmuş olsaydı, "Bu sizin için tüm kodunuzu yazmak için insanlar almak site tür değil" tarafından aşağı ve atladı olurdu üzücü bir durum.
dewd

Yanıtlar:


118

HTML 5 ile history.pushStateişlevi kullanın . Örnek olarak:

<script type="text/javascript">
var stateObj = { foo: "bar" };
function change_my_url()
{
   history.pushState(stateObj, "page 2", "bar.html");
}
var link = document.getElementById('click');
link.addEventListener('click', change_my_url, false);
</script>

ve bir href:

<a href="#" id='click'>Click to change url to bar.html</a>

URL'yi geri düğme listesine bir giriş eklemeden değiştirmek istiyorsanız, history.replaceStatebunun yerine kullanın.


Haklısın, en son Chrome'u denedim. Sadece Ubuntu'mda Firefox 3.6 ile denedim, işe yaramadı. HTML5'in FF'de tamamen desteklenmesini beklemek zorundayız
clu3

15
Örnek kod kesilir ve developer.mozilla.org/tr/DOM/Manipulating_the_browser_history adresinden yapıştırılır . Aslında bu durumda foo ve barın ne anlama geldiğini açıklıyor.
mikemaccana

2
Foo ve bar hiçbir şey ifade etmez, daha sonra geri alabileceğiniz keyfi olarak tanımlanmış bir durum nesnesidir.
Paul Dixon

3
@Paul: evet, yukarıdaki makale bu bilgiyi veriyor.
mikemaccana

2
Bu yorumu gönderdiği için firefox chrome ve safari üzerinde çalışır. Gerçi ipad veya iphone'da mobil safari ile şans yok :(
Sid

187

Eğer desteklemeyen tarayıcılarda çalışması için isterseniz history.pushStateve history.popStatehenüz "eski" yolu sayfayı yeniden neden olmaz betimleyici de, ayarlamaktır.

Temel fikir, window.location.hashözelliği ihtiyacınız olan durum bilgilerini içeren bir değere ayarlamaktır, ya da window.onhashchange olayını kullanın veya desteklemeyen eski tarayıcılar onhashchange(IE <8, Firefox <3.6) için düzenli olarak kontrol edin. karma değerinin değişip değişmediğine bakın ( setIntervalörneğin kullanarak ) ve sayfayı güncelleyin. İlk içeriği ayarlamak için sayfa yüklemesindeki karma değerini de kontrol etmeniz gerekir.

JQuery kullanıyorsanız , tarayıcının desteklediği yöntemi kullanacak bir karma değişim eklentisi vardır. Diğer kütüphaneler için de eklentiler olduğundan eminim.

Dikkat edilmesi gereken bir şey, sayfadaki kimliklerle çarpışmaktır, çünkü tarayıcı eşleşen bir kimliğe sahip herhangi bir öğeye kaydırır.


2
Arama motorları bu dahili bağlantıları (karma) yok saymıyor mu? Benim senaryomda örümceklerin de bu bağlantıları almasını istiyorum.
Drew Noakes

3
@Drew, bildiğim kadarıyla, arama motorlarının sayfanın bir bölümünü ayrı bir sonuç olarak ele almasının bir yolu yok.
Matthew Crumley

8
Artık arama motorlarının karmaları görmesini sağlamak için bir teklif var: googlewebmastercentral.blogspot.com/2009/10/…
LKM

5
Birini setIntervalincelemek için kullanmak yerine document.location.hash, hashchangeolayı çok daha fazla kabul edildiği için kullanabilirsiniz . Her bir standardı hangi tarayıcıların desteklediğini görmek için buraya bakın . Şu anki yaklaşımım push / popState'i destekleyen tarayıcılarda kullanmak. Diğerlerinde karmayı ayarlıyorum ve sadece hashchangedestekleyen tarayıcılarda izliyorum . Bu, geçmiş desteği olmadan IE <= 7 bırakır, ancak yararlı kalıcı bağlantı ile. Ama IE <= 7 tarihini kim umursar?
Irae Carvalho

2
@gabeDel Evet, Analytics’in karmayı kaydettiğini düşünmeme rağmen aynı URL’ye sahip olacak. Daha iyi bir yol _trackPageview, yeni sayfanın "gerçek" URL'sini manuel olarak aramak olabilir .
Matthew Crumley

37

window.location.href geçerli URL'yi içerir. Ondan okuyabilir, ekleyebilir ve değiştirebilirsiniz, bu da sayfanın yeniden yüklenmesine neden olabilir.

Göründüğü gibi, javascript durumunu URL'ye kaydetmek istiyorsanız, böylece sayfa yeniden yüklenmeden yer işareti konabilir, bir # işaretinden sonra geçerli URL'ye ekleyin ve onload olayı tarafından tetiklenen bir javascript parçası mevcut Kaydedilmiş durum içerip içermediğini görmek için URL.

Bir? # yerine, sayfanın yeniden yüklenmesini zorlarsınız, ancak kaydedilen durumu yükte ayrıştıracağınızdan bu aslında bir sorun olmayabilir; bu da ileri ve geri düğmelerinin düzgün çalışmasını sağlar.


2
javascript durumunu URL'ye kaydetme tam olarak yapmaya çalıştığım şey
Steven Noble

21

Bunun mümkün olmadığından şüphelenirim, çünkü olsaydı inanılmaz bir güvenlik sorunu olurdu. Örneğin, bir banka giriş sayfası gibi görünen bir sayfa yapabilir ve adres çubuğundaki URL'yi gerçek banka gibi gösterebilirim !

Belki bunu neden yapmak istediğinizi açıklarsanız, insanlar alternatif yaklaşımlar önerebilirler ...

[2011'de düzenle: Bu cevabı 2008'de yazdığım için , URL'nin aynı kaynaktan olduğu sürece değiştirilmesine izin veren bir HTML5 tekniği hakkında daha fazla bilgi ortaya çıktı ]


6
Yeniden yükleme olmayan değişiklikler yol, sorgu dizesi ve parçayla sınırlıysa, yani otorite (etki alanı ve benzeri) ile ilgili bir sorun değildir.
Ollie Saunders

2
youtube.com/user/SilkyDKwan#p/u/2/gTfqaGYVfMg bunun mümkün bir örnektir, video değiştirmeyi deneyin :)
Spidfire

Matthew Chumley'in kabul edilen cevapta belirttiği gibi location.hash'ı (# işaretinden sonraki her şey) değiştirebilirsiniz.
Paul Dixon

2
Facebook kullanıyor musunuz? Facebook URL'sini değiştirir olmadan kullanarak, geri doldurma history.pushState().
Derek 朕 會 功夫

Paul Dixon, facebook gelen kutusunu görmelisiniz, sol taraftaki isimlere tıkladığınızda, sadece URL değiştirilir ve sohbet kutusuna yeni sohbet yüklenir, sayfa yenilenmez. Ayrıca WebGL aynı şeyi yapmak çok daha fazla site var
Dheeraj Thedijje

8

Tarayıcı güvenlik ayarları kişilerin görüntülenen URL'yi doğrudan değiştirmesini önler. Neden olabilecek kimlik avı güvenlik açıklarını hayal edebilirsiniz.

Sayfa değiştirmeden url'yi değiştirmenin tek güvenilir yolu, dahili bir bağlantı veya karma kullanmaktır. örneğin: http://site.com/page.html olur http://site.com/page.html#item1 . Bu teknik genellikle hijax'ta kullanılır (AJAX + koruma geçmişi).

Bunu yaparken sık sık href olarak karma ile eylemler için bağlantılar kullanacağım, sonra eylemi belirlemek ve temsil etmek için istenen karma kullanan jquery ile tıklama olayları ekleyeceğim.

Umarım bu sizi doğru yola sokar.


Üzgünüm ama cevabınız doğru değil. Evet, URL'yi değiştirebilirsiniz.
Derek 朕 會 功夫

1
Evet, html5 geçmiş API'sini kullanabilirsiniz, ancak çapraz tarayıcı değildir, ancak karma URL'lere geri dönecek bir poli dolgu kullanabilirsiniz.
Jethro Larson

8

jQuery , jQuery-itici adı verilen tarayıcı URL'sini değiştirmek için harika bir eklentiye sahiptir .

JavaScript pushStateve jQuery birlikte kullanılabilir, örneğin:

history.pushState(null, null, $(this).attr('href'));

Misal:

$('a').click(function (event) {

  // Prevent default click action
  event.preventDefault();     

  // Detect if pushState is available
  if(history.pushState) {
    history.pushState(null, null, $(this).attr('href'));
  }
  return false;
});

Durumu değiştirdikten sonra oluşturulan XMLHttpRequest nesneleri için HTTP üstbilgisinde kullanılan yönlendireni değiştiren yalnızca JavaScript'i kullanma history.pushState().

Misal:

window.history.pushState("object", "Your New Title", "/new-url");

PushState () yöntemi:

pushState()üç parametre alır: bir durum nesnesi, bir başlık (şu anda yoksayılır) ve (isteğe bağlı olarak) bir URL. Bu üç parametrenin her birini daha ayrıntılı olarak inceleyelim:

  1. state nesnesi - state nesnesi, tarafından oluşturulan yeni geçmiş girdisiyle ilişkilendirilmiş bir JavaScript nesnesidir pushState(). Kullanıcı yeni duruma her gittiğinde, bir popstate olayı tetiklenir ve olayın state özelliği geçmiş girdisinin durum nesnesinin bir kopyasını içerir.

    Durum nesnesi serileştirilebilen herhangi bir şey olabilir. Firefox, durum tarayıcılarını kullanıcının diskine kaydettiğinden, kullanıcı tarayıcısını yeniden başlattıktan sonra geri yüklenebilmeleri için, bir durum nesnesinin serileştirilmiş gösterimine 640 bin karakter boyut sınırı koyarız. Serileştirilmiş temsili bundan daha büyük olan bir durum nesnesini iletirseniz pushState(), yöntem bir istisna atar. Bundan daha fazla alana ihtiyacınız varsa sessionStorage ve / veya localStorage kullanmanız önerilir.

  2. title - Firefox şu anda bu parametreyi yok sayar, ancak gelecekte de kullanabilir. Boş dizeyi buraya iletmek, yöntemde yapılacak değişikliklere karşı güvenli olmalıdır. Alternatif olarak, taşındığınız eyalet için kısa bir başlık da iletebilirsiniz.

  3. URL - Yeni geçmiş girişinin URL'si bu parametre tarafından verilir. Tarayıcının bir çağrıdan sonra bu URL'yi yüklemeyi denemeyeceğini pushState(), ancak örneğin kullanıcı tarayıcısını yeniden başlattıktan sonra URL'yi daha sonra yüklemeyi deneyebileceğini unutmayın. Yeni URL'nin mutlak olması gerekmez; göreli ise, geçerli URL'ye göre çözülür. Yeni URL, mevcut URL ile aynı kaynaktan olmalıdır; aksi takdirde pushState()bir istisna atar. Bu parametre isteğe bağlıdır; belirtilmezse, belgenin geçerli URL'sine ayarlanır.



3

Facebook'un fotoğraf galerisi bunu URL'de # hash kullanarak yapar. Aşağıda bazı örnek URL'ler verilmiştir:

'İleri'yi tıklamadan önce:

/photo.php?fbid=496429237507&set=a.218088072507.133423.681812507&pid=5887027&id=681812507

'İleri'yi tıkladıktan sonra:

/photo.php?fbid=496429237507&set=a.218088072507.133423.681812507&pid=5887027&id=681812507#!/photo.php?fbid=496435457507&set=a.218088072507.133423.681812507&pid=5887085&id=681812507

Hemen yeni URL'nin ardından karma-bang'a (#!) Dikkat edin.



2

Benim için çalışan şey - history.replaceState()aşağıdaki gibi işlev -

history.replaceState(data,"Title of page"[,'url-of-the-page']);

Bu sayfayı yeniden yüklemez, javascript olayı ile kullanabilirsiniz


1

Sayfadaki ana yol aynı olduğu sürece mümkün olup olmayacağını merak ediyordum, sadece yeni bir şey ekleniyor.

Diyelim ki kullanıcı sayfada: http://domain.com/site/page.html Diyelim ki tarayıcı yapmama izin veriyor location.append = new.html ve sayfa oluyor: http://domain.com/site/page.htmlnew.htmlve tarayıcı bunu değiştirmiyor.

Veya kişinin get parametresini değiştirmesine izin verin, hadi yapalım location.get = me=1&page=1.

Böylece orijinal sayfa olur http://domain.com/site/page.html?me=1&page=1ve yenilenmez.

# İle ilgili sorun karma değiştiğinde (en azından ben öyle düşünmüyorum) veri önbelleğe alınmamış olmasıdır. Bu nedenle, her yeni sayfa yüklenirken olduğu gibi, Ajax dışı bir sayfadaki geri ve ileri düğmeleri verileri önbelleğe alabilir ve verileri yeniden yüklemek için zaman harcamaz.

Gördüğüm kadarıyla, Yahoo geçmişi şey zaten tüm verileri bir kerede yükler. Herhangi bir Ajax isteği yapmıyor gibi görünüyor. Bu nedenle, a div, farklı yöntem fazla mesai işlemek için kullanıldığında, bu veriler her geçmiş durumu için saklanmaz.


1

kodum:

//change address bar
function setLocation(curLoc){
    try {
        history.pushState(null, null, curLoc);
        return false;
    } catch(e) {}
        location.hash = '#' + curLoc;
}

ve aksiyon:

setLocation('http://example.com/your-url-here');

ve örnek

$(document).ready(function(){
    $('nav li a').on('click', function(){
        if($(this).hasClass('active')) {

        } else {
            setLocation($(this).attr('href'));
        }
            return false;
    });
});

Bu kadar :)


1

Daha basit bir cevap sunuyorum,

window.history.pushState(null, null, "/abc")

bu /abc, tarayıcı URL'sindeki alan adından sonra eklenir . Bu kodu kopyalayıp tarayıcı konsoluna yapıştırın ve URL'nin " https://stackoverflow.com/abc " olarak değiştiğini görün


0

Şununla başarılı oldum:

location.hash="myValue";

Yalnızca #myValuegeçerli URL'ye eklenir . Yükleme sayfasındaki bir olayı tetiklemeniz gerekiyorsa location.hash, ilgili değeri kontrol etmek için aynı olayı kullanabilirsiniz . Örneğin #tarafından döndürülen değerden kaldırmayı unutmayın.location.hash

var articleId = window.location.hash.replace("#","");
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.