HTML5 Geçmiş API'sını (Pushstate?) Kullanmak için iyi bir öğretici [kapalı]


168

AJAX yüklü içerik ile derin bağlantı sorunlarını çözmek için HTML5 Geçmiş API kullanarak arıyorum, ama yerden kurtulmak için mücadele ediyorum. İyi kaynakları bilen var mı?

Bu linkler JS açık olmayabilir gönderilen gönderilmesi olasılığı izin vermek için harika bir yol gibi görünüyor bu kullanmak istiyorum. JS'li bir kişi, olmayan bir kişiye bir bağlantı gönderdiğinde birçok çözüm başarısız olur.

İlk araştırmam JS içindeki bir Geçmiş API'sına ve pushState yöntemine işaret ediyor gibi görünüyor.

http://html5demos.com/history

Yanıtlar:


181

Harika bir eğitim için bu işleve ilişkin Mozilla Geliştirici Ağı sayfası tek ihtiyacınız olan şey: https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history

Ne yazık ki, HTML5 Geçmişi API'sı tüm HTML5 tarayıcılarında farklı şekilde uygulanır (tutarsız ve buggy yapar) ve HTML4 tarayıcıları için herhangi bir geri dönüşü yoktur. Neyse ki, History.js HTML5 tarayıcıları için çapraz uyumluluk sağlar (tüm HTML5 tarayıcılarının beklendiği gibi çalışmasını sağlar) ve isteğe bağlı olarak HTML4 tarayıcıları için karma veriler sağlar (veriler, başlıklar, pushState ve replaceState işlevleri için sürekli destek dahil).

History.js hakkında daha fazla bilgiyi buradan edinebilirsiniz: https://github.com/browserstate/history.js

Hashbangs VS Hashes VS HTML5 Geçmişi API'si hakkında bir makale için buraya bakın: https://github.com/browserstate/history.js/wiki/Intelligent-State-Handling


25
Utanmaz kendinden fişli. Mükemmel yazı ve eklenti olsa. :)
Purag


28

Bir kullanıcı derin bir bağlantıyı kopyalar veya yer işareti eklerse ve tekrar ziyaret ederse HTML5 pushstate'i kullanırken aklınızda bulundurun, o zaman 404 olacak doğrudan bir sunucu vuruşu olacaktır, bu yüzden buna hazır olmanız gerekir ve bir pushstate js kütüphanesi bile yardımcı olmaz sen. En kolay çözüm, Nginx veya Apache sunucunuza şu şekilde bir yeniden yazma kuralı eklemektir:

Apache (eğer kullanıyorsanız hayaletinizde):

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.html$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.html [L]
 </IfModule>

nginx

rewrite ^(.+)$ /index.html last;

Bu gerçek cevap. Bu Balupton'un History.js wiki / öğreticileri vb. Üzerinde hiçbir yerde değildir. Aslında, History.js karma kullanmaz, bu nedenle bir .htaccess yönlendirmesi kullanmanız gerekir!
adriendenat

13
İdeal olarak, sunucunuz / uygulamanız bu yeniden yazmaya gerek kalmadan yola uygun şekilde yanıt vermelidir.
sholsinger

Backbone.js, Spine, Ember, vb.Gibi birçok modern JavaScript çerçevesi hariç, kabul edildi. Bunların hepsi "tek sayfalık" JavaScript uygulamalarıdır. Bir SEO, vb için yazma arka uç şablonu hizmet veren bir çözüm işe yarayabilir, ancak bu arada bu gerekli olacaktır.
Mauvis Ledford

*sağ. Burada daha ayrıntılı olarak bu konuda yazmak: readystate4.com/2012/05/17/...
Mauvis Ledford

6

HTML5 geçmişi Spec ilginç.

history.pushState()popstatekendi başına bir etkinlik göndermez veya yeni bir sayfa yüklemez. Sadece devleti tarihe itmek içindi. Bu, tek sayfa uygulamaları için bir "geri al" özelliğidir. Bir popstateolayı manuel olarak göndermeniz veya history.go()yeni duruma gitmek için kullanmanız gerekir. Fikir şu ki, bir yönlendirici popstateolayları dinleyebilir ve sizin için navigasyonu yapabilir.

Dikkat edilmesi gereken bazı noktalar:

  • history.pushState()ve olayları history.replaceState()göndermeyin popstate.
  • history.back(),, history.forward()ve tarayıcının geri ve ileri düğmeleri gönderme popstateolayları yapar.
  • history.go()ve history.go(0)tam sayfa yeniden yükleme yapın ve popstateetkinlik göndermeyin .
  • history.go(-1)(1 sayfa geri) ve history.go(1)(1 sayfa ileri) dağıtım popstateolayları yapar.

Yeni bir durumu zorlamak ve bir popstate olayı göndermek için geçmiş API'sını böyle kullanabilirsiniz.

history.pushState({message:'New State!'}, 'New Title', '/link'); window.dispatchEvent(new PopStateEvent('popstate', { bubbles: false, cancelable: false, state: history.state }));

Ardından popstateyönlendirici ile olayları dinleyin .


1
Sadece ben mi, yoksa new PopStateEvent(...)IE11'de çalışmıyor mu? Herkesin bildiği bir geçici çözüm var mı?
David Alan Hjelle

Görünüşe göre IE 11 gibi bir şeye ihtiyaç duyuyor: var pop_state_event = document.createEvent('Event'); pop_state_event.initEvent('popstate', true, true); window.dispatchEvent(pop_state_event);
David Alan Hjelle

4

Davis.js'yi deneyebilirsiniz , mevcut olduğunda pushState'i kullanarak JavaScript'inize yönlendirmenizi sağlar ve JavaScript olmadan sunucu tarafı kodunuzun istekleri işlemesine izin verir.



2

Bu jQuery eklentisine bir göz atmak isteyebilirsiniz. Sitelerinde çok sayıda örnek var. http://www.asual.com/jquery/address/


Yine, JS kapalıyken bu çözüm başarısız görünüyor. Geçmiş API'sı modrewrite ile birlikte çalışma gücüne sahip olduğunu düşünüyorum, böylece bağlantılar her zaman ilk kez sunucu tarafından JS katmanından yeniden yönlendirmeye gerek kalmadan işlenir.
Hafif Fuzz

Modrewrite ile doğru yoldasınız. Geçmiş API'sini yönetme ve kullanıcının JS'si olmadığında işleme çözümü gerçekten iki ayrı şeydir. JS'niz yoksa, kullanıcıyı standart hrefs ve sunucu yanıtlarıyla ele almanız gerekir. Geçmişin API'sı, kullanıcının tarayıcısı destekliyorsa bir tür "olması güzel" olarak oluşturulabilir.
Nathan Totten

JQuery Address 1.3 ile birlikte gelen Express ve State örnekleri JavaScript devre dışı bırakıldığında oldukça iyi çalışır. İkincisi mod_rewrite ile PHP kullanır.
Rostislav

Kesinlikle benim inceliğim. JS olmadan site oluşturmak, AJAX öğeleri eklemek ve daha sonra derin bağlantı koruyarak URL'yi yeniden yazmak için geçmişi kullanmak niyetindeyim. Teorik olarak, site herhangi bir aşamada
AJAX'a

1
JQuery Adresi olarak -1, HTML5 Durum API'sinin doğrudan bir bağlantı noktası değildir; verileri veya başlıkları ve replaceState'i desteklemez.
balupton

2

History.js'nin üzerine StateRouter.js adında çok basit bir yönlendirici soyutlaması yazdım . Gelişimin çok erken aşamalarında, ancak yazdığım tek sayfalık bir uygulamada yönlendirme çözümü olarak kullanıyorum. Sizin gibi, History.js'yi kavramak çok zor buldum, özellikle de JavaScript için oldukça yeni olduğum için, üst düzey bir yönlendirme soyutlamasına ihtiyacınız olduğunu (veya olması gerektiğini) anlayana kadar, düşük seviyeyi çözdüğü için sorun.

Bu basit örnek kod nasıl kullanıldığını göstermelidir:

var router = new staterouter.Router();
// Configure routes
router
  .route('/', getHome)
  .route('/persons', getPersons)
  .route('/persons/:id', getPerson);
// Perform routing of the current state
router.perform();

İşte kullanımını göstermek için uydurduğum küçük bir keman .


1
Bu keman Mac'te Chrome'da benim için çalışmıyor. Bir hata veriyor. (Yakalanmayan ReferenceError: staterouter tanımlanmamış)
DrewT

@DrewT Teşekkürler, github.com'daki bir değişiklik nedeniyle keman kırıldı, ancak etrafında çalıştım.
aknuds1

Evet, şimdi çalışıyor hızlı yanıt için teşekkürler.
DrewT

1

jQuery mevcutsa, jQuery BBQ kullanabilirsiniz


JS kapalıyken bu başarısız görünüyor.
Hafif Fuzz

bu muhtemelen doğrudur - içine bakmadım. Tüm js-library-based yaklaşımlarda bu problemi yaşayacağınızı düşünüyorum. URL'nin karma bölümünü değiştirmeye dayanıyorlar.
sprugman

1
HTML5 Geçmiş API'sının noktası budur - hiçbir şey
kırmaz

2
@MildFuzz Bilgisayar güç kaynağı olmadan arızalanıyor gibi görünüyor! Sanırım ID-10-T hatası var ...
Eric Hodonsky

1
İronik olarak, misundestood olan sensin
Mild Fuzz
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.