On - window.location.hash - Değiştir?


558

Navigasyon için Ajax ve karma kullanıyorum.

Kontrol etmenin bir yolu var mı window.location.hash değişip değişmediğini ?

http://example.com/blah # 123 ila http://example.com/blah # 456

Belge yüklendiğinde kontrol edersem çalışır.

Ancak #hash tabanlı navigasyonum varsa, tarayıcıdaki geri düğmesine bastığımda işe yaramaz (bu yüzden # 456'dan blah # 123'e atlarım).

Adres kutusunun içinde görünüyor, ancak JavaScript ile yakalayamıyorum.


6
Bu jquery eklentisine göz atın
Xavi

9
History.js , HTML5 Durum Yönetimi İşlevselliğini destekler (bu nedenle artık karma kullanmanıza gerek yoktur!) Ve hashchanges kullanarak HTML4 tarayıcılarına incelikle indirir. Kutusundan çıkan jQuery, MooTools ve Prototype'i destekler.
balupton

@balupton, Aslında , URL değiştirmeyi geri bildirim olarak kullanmadığınız sürece, kullanıcıya geçmişine "yeni bir sayfa" eklendiğini bildirmek için hala karma kullanmamız gerekir .
Pacerier


hmm ... Sanırım moar jQuery
RaisingAgent

Yanıtlar:


617

Bunu gerçekten yapmanın tek yolu (ve 'gerçekten basit tarih' bunu nasıl yapıyor), mevcut karmayı kontrol etmeye devam eden bir aralık belirleyerek ve bunu daha önce olduğu ile karşılaştırarak, bunu yaparız ve abonelerin değişmiş bir aboneye abone olmasına izin veririz karma değiştiğinde ateş ettiğimiz olay .. mükemmel değil ama tarayıcılar bu olayı doğal olarak desteklemiyor.


Bu yanıtı güncel tutmak için güncelleyin:

JQuery kullanıyorsanız (bugün çoğu için biraz temel olmalıdır) o zaman güzel bir çözüm, jQuery'nin pencere nesnesindeki hashchange olaylarını dinlemek için kendi olay sistemini kullanarak size verdiği soyutlamayı kullanmaktır.

$(window).on('hashchange', function() {
  //.. work ..
});

Burada güzel bir şey, karma desteği hakkında endişelenmenize gerek olmayan bir kod yazabilirsiniz, ancak biraz daha az bilinen jQuery özelliği jQuery özel etkinlikler şeklinde biraz sihir yapmalısınız .

Bu özellik sayesinde, herhangi bir olay için bazı kurulum kodlarını çalıştırırsınız, birisi ilk kez olayı herhangi bir şekilde kullanmaya çalıştığında (olaya bağlanma gibi).

Bu kurulum kodunda yerel tarayıcı desteğini kontrol edebilirsiniz ve tarayıcı bunu yerel olarak uygulamazsa, değişiklikleri yoklamak için tek bir zamanlayıcı ayarlayabilir ve jQuery olayını tetikleyebilirsiniz.

Bu, kodunuzu bu destek sorununu anlamaya ihtiyaç duymadan tamamen engeller, bu tür özel bir etkinliğin uygulanması önemsizdir (basit bir% 98 çalışma sürümü elde etmek için), ancak neden başka biri zaten varsa bunu yapar .


7
IE8 yapar. Daha fazlası
Sergey Ilinsky

28
En yeni Firefox derlemesi (3.6 alfa) artık yerel karma değiştirilmiş etkinliği de destekliyor: developer.mozilla.org/en/DOM/window.onhashchange Bu etkinlik için bir kontrol yapmaya kesinlikle değer, ancak IE8'in size etkinliği söyleyeceğini unutmayın IE7 uyumluluk modunda çalışırken var olur ... ne yazık ki olay tetiklenmiyor .. olayı kontrol etmeniz gerekecek ve tarayıcının IE7 gibi görünmediği .. iç çekme (ya da olayı tetiklemeye çalışma IE'nin fireEvent yöntemi ile).
meandmycode

8
Yazma sırasında, WebKit de hashchangeolayı tetiklerken , Safari (kararlı) henüz değil.
jholster

51
Sadece başka bir güncelleme daha eklemek için, hashchangeetkinlik artık geniş çapta desteklenmektedir: caniuse.com/#search=hash
Paystey

19
İstenmeyen jQuery cevaplarının acı olduğunu düşünen tek kişi ben miyim?
Luc

290

HTML5 bir hashchangeolay belirtir . Bu etkinlik artık tüm modern tarayıcılar tarafından desteklenmektedir . Aşağıdaki tarayıcı sürümlerinde destek eklendi:

  • Internet Explorer 8
  • Firefox 3.6
  • Chrome 5
  • Safari 5
  • Opera 10.6

20
Güncelleme: FF 5, Safari 5 ve Chrome 12, Haziran 2011 itibarıyla bu etkinliği destekliyor.
james.garriss

2
İşte hashchange için CanIUse sayfası . İşte quirksmode hashchange . IE desteği, büyük / küçük harf duyarlılığı açısından hatalı.
Tobu

3
@everybody, yorum bölümündeki cevaba eklemeye devam etmenize gerek yok - "Düzenle" düğmesinin amacı budur. :)
Michael Martin-Smucker

15
kullanım:window.onhashchange = function() { doYourStuff(); }
Chris

4
Hashchange olayının MDN belgeleri .
Dabowheel

52

Internet Explorer 7 ve Internet Explorer 9'da ififadenin doğru olacağını (pencerelerde "onhashchange" için), ancak window.onhashchangeasla tetiklenmeyeceğini unutmayın , bu nedenle karma depolamak ve her 100 milisaniyeden sonra değiştirilip değiştirilmediğini kontrol etmek daha iyidir. Internet Explorer'ın tüm sürümleri için.

    if (("onhashchange" in window) && !($.browser.msie)) {
         window.onhashchange = function () {
              alert(window.location.hash);
         }
         // Or $(window).bind( 'hashchange',function(e) {
         //       alert(window.location.hash);
         //   });
    }
    else {
        var prevHash = window.location.hash;
        window.setInterval(function () {
           if (window.location.hash != prevHash) {
              prevHash = window.location.hash;
              alert(window.location.hash);
           }
        }, 100);
    }

EDIT - jQuery 1.9 olduğundan $.browser.msie, desteklenmez. Kaynak: http://api.jquery.com/jquery.browser/


14

IE tarayıcılarda Geçmiş ve window.location.hash ile uğraşmak için bir sürü püf noktası var:

  • Orijinal sorunun söylediği gibi, a.html # b sayfasından a.html # c'ye gidip geri düğmesine basarsanız, tarayıcı sayfanın değiştiğini bilmez. Bir örnekle söyleyeyim: window.location.href, a.html # b veya a.html # c olsun, 'a.html # c' olacaktır.

  • Aslında a.html # b ve a.html # c geçmişte yalnızca sayfada '<a name="#b">' ve '<a name="#c">' öğeleri varsa saklanır .

  • Ancak, bir sayfanın içine bir iframe koyarsanız, o iframe'deki a.html # b'den a.html # c'ye gidin ve geri düğmesine basın, iframe.contentWindow.document.location.href beklendiği gibi değişir.

  • Kodunuzda 'document.domain = bir şey ' kullanırsanız , iframe.contentWindow.document.open () 'işlevine erişemezsiniz (ve birçok Geçmiş Yöneticisi bunu yapar)

Bunun gerçek bir yanıt olmadığını biliyorum, ama belki IE-History notları birisi için yararlıdır.




9

"Window.location" nesnesinin "hash" özelliğine kolayca bir gözlemci ("watch" yöntemi) uygulayabilirsiniz.

Firefox'un nesne değişikliklerini izlemek için kendi uygulaması vardır , ancak başka bir uygulama kullanıyorsanız ( JavaScript'te nesne özellikleri değişikliklerini izle gibi ) - diğer tarayıcılar için bu işe yarayacaktır.

Kod şöyle görünecektir:

window.location.watch(
    'hash',
    function(id,oldVal,newVal){
        console.log("the window's hash value has changed from "+oldval+" to "+newVal);
    }
);

Sonra test edebilirsiniz:

var myHashLink = "home";
window.location = window.location + "#" + myHashLink;

Ve tabii ki bu sizin gözlemci fonksiyonunuzu tetikleyecektir.


Daha iyi kullanın: window.location yerine window.location.href.
Codebeat

3
Window.location.hash'ı izliyor, window.location'u değil.
undefined

1
@BrianMortenson: Dokümanlara göre ( developer.mozilla.org/en-US/docs/JavaScript/Reference/… ) watchdeğişen mülkün sahibi olan nesneye başvurmanız gerekir ve bunu gözlemlemek istersiniz.
gion_13

@ gion_13 Evet, tam olarak bunu belirtmeye çalışıyordum. 'O' ile kastetmiştim ve bu Erwinus'un yorumuna yönlendirilmişti. Daha açık olmalıydım. Açıklayıcı yorumun için teşekkürler.
undefined

7

Ben bir reaksiyon uygulamasında URL görünüyordu kullanıcının hangi görünümüne bağlı olarak farklı parametreler yapmak için kullanıyordum.

Hash parametresini kullanarak izledim

window.addEventListener('hashchange', doSomethingWithChangeFunction());

Sonra

doSomethingWithChangeFunction () { 
    // Get new hash value
    let urlParam = window.location.hash;
    // Do something with new hash value
};

Bir tedavi çalıştı, ileri ve geri tarayıcı düğmeleriyle ve ayrıca tarayıcı geçmişinde çalışır.


1
senin içinde addEventListenerçağrı, kaldırmak gerekir ()dandoSomethingWithChangeFunction
Jason S

() Öğesini kaldırmak için bir neden sunabilir misiniz? Ben de çalışacağını biliyorum ve daha az kod çoğunlukla daha iyi bir seçenektir, ancak bu yedeklemek için önemli bir neden olmadığı sürece bu seçici görünüyor?
Sprose

6
? ile çalışmamalı (). addEventListenerİşlevi, bir işlevde geçmek gerekir. doSomethingWithChangeFunctionbir işlevdir. doSomethingWithChangeFunction()bu durumda bir işlev olmayan o işlevin dönüş değeridir.
Jason S

6

İyi bir uygulama http://code.google.com/p/reallysimplehistory/ adresinde bulunabilir. . Sahip olduğu tek (ve aynı zamanda) sorun ve hata: Internet Explorer'da konum karmasını manuel olarak değiştirmek tüm geçmiş yığınını sıfırlayacaktır (bu bir tarayıcı sorunudur ve çözülemez).

Not, Internet Explorer 8'in "hashchange" olayı için desteği vardır ve HTML5'in bir parçası olduğu için diğer tarayıcıların yetişmesini bekleyebilirsiniz.


1

Başka bir harika uygulama, tarayıcı tarafından destekleniyorsa yerel onhashchange olayını kullanacak olan jQuery Geçmişidir, eğer değilse, beklenen tüm işlevlerin başarıyla taklit edildiğinden emin olmak için tarayıcı için uygun bir iframe veya aralık kullanır. Ayrıca belirli durumlara bağlanmak için güzel bir arayüz sağlar.

Dikkat çekmeye değer bir başka proje de jQuery History'nin karışıma ajax eklemesi için bir uzantı olan jQuery Ajaxy . Hashleri ​​ile ajax kullanmaya başladığınızda olduğu gibi oldukça karmaşık !


1
var page_url = 'http://www.yoursite.com/'; // full path leading up to hash;
var current_url_w_hash = page_url + window.location.hash; // now you might have something like: http://www.yoursite.com/#123

function TrackHash() {
    if (document.location != page_url + current_url_w_hash) {
        window.location = document.location;
    }
    return false;
}
var RunTabs = setInterval(TrackHash, 200);

Hepsi bu ... şimdi, geri veya ileri düğmelerine her bastığınızda, sayfa yeni karma değerine göre yeniden yüklenecek.


eval dize kullanmayın
Vitim.us

1

Istemci tarafı yönlendirme için path.js kullanıyorum. Oldukça özlü ve hafif buldum (NPM'de de yayınlandı) ve karma tabanlı navigasyon kullanıyor.

path.js NPM

path.js GitHub


0

Bir jQuery eklentisi HUtil kullandım ve üstüne YUI Geçmişi gibi bir arayüz yazdım .

Bir kez kontrol et. Yardıma ihtiyacın olursa yardım edebilirim.

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.