Tutorial yang bagus untuk menggunakan API Riwayat HTML5 (Pushstate?) [Ditutup]

168

Saya melihat ke dalam menggunakan API Sejarah HTML5 untuk menyelesaikan masalah penautan yang mendalam dengan konten yang dimuat AJAX, tapi saya berjuang untuk keluar dari tanah. Apakah ada yang tahu sumber daya yang bagus?

Saya ingin menggunakan ini karena tampaknya cara yang bagus untuk memungkinkan kemungkinan mereka yang mengirim tautan mungkin tidak mengaktifkan JS. Banyak solusi gagal ketika seseorang dengan JS mengirim tautan ke seseorang tanpa.

Penelitian awal saya tampaknya mengarah ke API Sejarah dalam JS, dan metode pushState.

http://html5demos.com/history

Fuzz Ringan
sumber

Jawaban:

181

Untuk tutorial yang luar biasa, halaman Jaringan Pengembang Mozilla tentang fungsi ini yang Anda butuhkan: https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history

Sayangnya, HTML5 History API diimplementasikan secara berbeda di semua browser HTML5 (membuatnya tidak konsisten dan bermasalah) dan tidak memiliki cadangan untuk browser HTML4. Untungnya, History.js memberikan kompatibilitas silang untuk browser HTML5 (memastikan semua browser HTML5 berfungsi seperti yang diharapkan) dan secara opsional menyediakan hash-fallback untuk browser HTML4 (termasuk dukungan yang dipertahankan untuk data, judul, fungsi pushState dan replaceState).

Anda dapat membaca lebih lanjut tentang History.js di sini: https://github.com/browserstate/history.js

Untuk artikel tentang Hashbangs VS Hash VS HTML5 History API, lihat di sini: https://github.com/browserstate/history.js/wiki/Intelligent-State-Handling

balupton
sumber
25
Steker mandiri tanpa malu-malu. Pos dan plugin yang luar biasa. :)
Purag
28

Perlu diingat saat menggunakan pushstate HTML5 jika pengguna menyalin atau menandai tautan yang dalam dan mengunjunginya lagi, maka itu akan menjadi hit server langsung yang akan 404 sehingga Anda harus siap untuk itu dan bahkan perpustakaan pushstate js tidak akan membantu kamu. Solusi termudah adalah menambahkan aturan penulisan ulang ke server Nginx atau Apache Anda seperti:

Apache (di vhost Anda jika Anda menggunakannya):

<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;
Mauvis Ledford
sumber
ITULAH jawaban yang sebenarnya. Ini tidak ada di wiki / tutorial Balupton's History.js dll. Sebenarnya, History.js tidak menggunakan hash sehingga Anda perlu menggunakan pengalihan .htaccess!
adriendenat
13
Idealnya server / aplikasi Anda harus merespons rute dengan tepat tanpa perlu menulis ulang ini.
sholsinger
Setuju, kecuali dalam banyak kerangka kerja JavaScript modern seperti Backbone.js, Spine, Ember, dll. Ini semua pada dasarnya adalah aplikasi JavaScript "satu halaman". Orang bisa menemukan solusi melayani template backend tulis untuk SEO, dll, tetapi sementara ini akan diperlukan.
Mauvis Ledford
*Baik. Saya menulis tentang ini lebih terinci di sini: readystate4.com/2012/05/17/…
Mauvis Ledford
6

The sejarah HTML5 spesifikasi unik.

history.pushState()tidak mengirim popstateacara atau memuat halaman baru dengan sendirinya. Itu hanya dimaksudkan untuk mendorong negara ke dalam sejarah. Ini adalah fitur "undo" untuk aplikasi satu halaman. Anda harus secara manual mengirim popstateacara atau menggunakan history.go()untuk menavigasi ke negara baru. Idenya adalah router dapat mendengarkan popstateacara dan melakukan navigasi untuk Anda.

Beberapa hal yang perlu diperhatikan:

  • history.pushState()dan history.replaceState()jangan kirim popstateacara.
  • history.back(),, history.forward()dan tombol kembali dan maju browser melakukan pengiriman popstateacara.
  • history.go()dan history.go(0)memuat ulang satu halaman penuh dan tidak mengirim popstateacara.
  • history.go(-1)(belakang 1 halaman) dan history.go(1)(maju 1 halaman) melakukan pengiriman popstateacara.

Anda dapat menggunakan API riwayat seperti ini untuk mendorong status baru DAN mengirim acara popstate.

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

Kemudian dengarkan popstateacara dengan router.

Erik Ringsmuth
sumber
1
Apakah hanya saya, atau new PopStateEvent(...)sepertinya tidak berfungsi di IE11? Apakah ada solusi yang diketahui orang?
David Alan Hjelle
Sepertinya IE 11 membutuhkan sesuatu seperti: var pop_state_event = document.createEvent('Event'); pop_state_event.initEvent('popstate', true, true); window.dispatchEvent(pop_state_event);
David Alan Hjelle
4

Anda dapat mencoba Davis.js , ini memberi Anda perutean di JavaScript menggunakan pushState bila tersedia dan tanpa JavaScript memungkinkan kode sisi server Anda untuk menangani permintaan.

Oliver Nightingale
sumber
4

Berikut ini adalah screen-cast yang bagus untuk topik oleh Ryan Bates dari railscasts. Pada akhirnya ia hanya menonaktifkan fungsionalitas ajax jika metode history.pushState tidak tersedia:

http://railscasts.com/episodes/246-ajax-history-state

deb
sumber
2

Anda mungkin ingin melihat plugin jQuery ini. Mereka memiliki banyak contoh di situs mereka. http://www.asual.com/jquery/address/

Nathan Totten
sumber
Sekali lagi, solusi ini tampaknya gagal ketika JS mati. Saya pikir sejarah API memiliki kekuatan untuk bekerja bersama dengan modrewrite sehingga tautan selalu diproses pada contoh pertama oleh server, tanpa perlu pengalihan dari lapisan JS.
Mild Fuzz
Anda berada di jalur yang benar dengan modrewrite. Solusi mengelola API riwayat dan penanganan ketika pengguna tidak memiliki JS adalah dua hal yang terpisah. Jika Anda tidak memiliki JS, Anda harus menangani pengguna dengan standar hrefs dan respons server. API riwayat dapat dibuat sebagai "fasilitas yang bagus" jika browser pengguna mendukungnya.
Nathan Totten
Sampel Express dan State yang dikirimkan dengan jQuery Address 1.3 berfungsi dengan cukup baik ketika JavaScript dinonaktifkan. Yang kedua menggunakan PHP dengan mod_rewrite.
Rostislav
Kebijaksanaan saya tepat. Saya bermaksud membangun situs tanpa JS, menambahkan elemen AJAX dan kemudian menggunakan histori untuk menulis ulang URL, menjaga tautan dalam. Secara teoritis, itu harus menjadi metode yang lebih baik daripada yang saya lihat karena situs tidak akan bergantung pada AJAX, pada tahap apa pun
Mild Fuzz
1
-1 sebagai Alamat jQuery bukan port langsung API HTML5 State - tidak mendukung data atau judul, dan replaceState.
balupton
2

Saya telah menulis abstraksi router yang sangat sederhana di atas History.js, yang disebut StateRouter.js . Ini masih dalam tahap awal pengembangan, tetapi saya menggunakannya sebagai solusi perutean dalam aplikasi satu halaman yang saya tulis. Seperti Anda, saya menemukan History.js sangat sulit untuk dipahami, terutama karena saya cukup baru untuk JavaScript, sampai saya mengerti bahwa Anda benar-benar membutuhkan (atau seharusnya memiliki) abstraksi perutean di atasnya, karena ia menyelesaikan level rendah masalah.

Contoh kode sederhana ini harus menunjukkan bagaimana itu digunakan:

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

Berikut adalah biola kecil yang saya buat untuk menunjukkan penggunaannya.

aknuds1
sumber
1
Biola ini tidak berfungsi untuk saya di Chrome di Mac. Itu melempar kesalahan. (Uncaught ReferenceError: staterouter tidak ditentukan)
DrewT
@DrewT Terima kasih, biola rusak karena perubahan di github.com, tapi saya sudah mengatasinya.
aknuds1
Yup, bekerja sekarang terima kasih atas respon cepatnya.
DrewT
1

jika jQuery tersedia, Anda bisa menggunakan jQuery BBQ

Sprugman
sumber
Ini tampaknya gagal dengan JS dimatikan.
Mild Fuzz
itu mungkin benar - belum memeriksanya. Saya akan berpikir bahwa Anda akan memiliki masalah dengan semua pendekatan berbasis js-library. Mereka didasarkan pada memanipulasi bagian hash dari url.
sprugman
1
itulah poin dari API Sejarah HTML5 - tidak merusak apa pun
balupton
2
@MildFuzz Computer tampaknya gagal tanpa sumber daya! Saya pikir Anda memiliki kesalahan ID-10-T ...
Eric Hodonsky
1
Ironisnya, Andalah yang salah paham
Mild Fuzz