Saya menggunakan jQuery Mobile, dan saya mengalami kesulitan memahami perbedaan antara acara halaman siap dokumen klasik dan jQuery Mobile.
Apa perbedaan sebenarnya?
Kenapa harus
<!-- language: lang-js --> $(document).ready() { });
lebih baik dari
$(document).on('pageinit') { });
Apa urutan kejadian halaman, ketika Anda beralih dari satu halaman ke halaman lainnya?
Bagaimana saya bisa mengirim data dari satu halaman ke halaman lain dan apakah mungkin untuk mengakses data dari halaman sebelumnya?
javascript
jquery
html
jquery-mobile
cordova
pengguna2001897
sumber
sumber
Jawaban:
Pembaruan jQuery Mobile 1.4:
Artikel asli saya dimaksudkan untuk cara penanganan halaman yang lama, pada dasarnya segalanya sebelum jQuery Mobile 1.4. Cara penanganan lama sekarang sudah usang dan akan tetap aktif sampai (termasuk) jQuery Mobile 1.5, sehingga Anda masih dapat menggunakan semua yang disebutkan di bawah ini, setidaknya sampai tahun depan dan jQuery Mobile 1.6.
Acara lama, termasuk pageinit tidak ada lagi, mereka diganti dengan widget pagecontainer . Pageinit terhapus sepenuhnya dan Anda dapat menggunakan pagecreate sebagai gantinya, acara itu tetap sama dan tidak akan diubah.
Jika Anda tertarik dengan cara baru penanganan acara halaman lihat di sini , dalam hal lain merasa bebas untuk melanjutkan dengan artikel ini. Anda harus membaca jawaban ini bahkan jika Anda menggunakan jQuery Mobile 1.4 +, itu melampaui peristiwa halaman sehingga Anda mungkin akan menemukan banyak informasi yang berguna.
Konten yang lebih lama:
Artikel ini juga dapat ditemukan sebagai bagian dari blog saya DI SINI .
$(document).on('pageinit')
vs.$(document).ready()
Hal pertama yang Anda pelajari di jQuery adalah memanggil kode di dalam
$(document).ready()
fungsi sehingga semuanya akan dijalankan segera setelah DOM dimuat. Namun, di jQuery Mobile , Ajax digunakan untuk memuat konten setiap halaman ke DOM saat Anda menavigasi. Karena ini$(document).ready()
akan memicu sebelum halaman pertama Anda dimuat dan setiap kode yang dimaksudkan untuk manipulasi halaman akan dieksekusi setelah refresh halaman. Ini bisa menjadi bug yang sangat halus. Pada beberapa sistem mungkin terlihat berfungsi dengan baik, tetapi pada yang lain mungkin menyebabkan keanehan, sulit untuk mengulangi keanehan terjadi.Sintaks jQuery klasik:
Untuk mengatasi masalah ini (dan percayalah ini masalah), pengembang jQuery Mobile membuat acara laman. Singkatnya, acara adalah peristiwa yang dipicu pada titik tertentu dari eksekusi halaman. Salah satu acara halaman tersebut adalah acara pageinit dan kita dapat menggunakannya seperti ini:
Kita dapat melangkah lebih jauh dan menggunakan id halaman alih-alih pemilih dokumen. Katakanlah kita memiliki halaman jQuery Mobile dengan indeks id :
Untuk mengeksekusi kode yang hanya akan tersedia untuk halaman indeks kita bisa menggunakan sintaks ini:
Acara Pageinit akan dieksekusi setiap halaman waktu akan dimuat dan ditampilkan untuk pertama kalinya. Itu tidak akan memicu lagi kecuali halaman di-refresh secara manual atau memuat halaman Ajax dimatikan. Jika Anda ingin kode dijalankan setiap kali Anda mengunjungi halaman, lebih baik menggunakan acara pagebeforeshow .
Berikut ini contoh yang berfungsi: http://jsfiddle.net/Gajotres/Q3Usv/ untuk mendemonstrasikan masalah ini.
Lebih sedikit catatan tentang pertanyaan ini. Tidak masalah jika Anda menggunakan 1 html banyak halaman atau beberapa paradigma file HTML, disarankan untuk memisahkan semua penanganan halaman JavaScript khusus Anda menjadi satu file JavaScript terpisah. Ini akan mencatat membuat kode Anda lebih baik tetapi Anda akan memiliki gambaran umum kode yang lebih baik, terutama saat membuat aplikasi jQuery Mobile .
Ada juga acara jQuery Mobile khusus dan disebut mobileinit . Ketika jQuery Mobile mulai, itu memicu acara mobileinit pada objek dokumen. Untuk mengganti pengaturan default, ikatkan ke mobileinit . Salah satu contoh yang baik dari penggunaan mobileinit adalah mematikan pemuatan halaman Ajax, atau mengubah perilaku loader Ajax default.
Urutan transisi acara laman
Pertama semua acara dapat ditemukan di sini: http://api.jquerymobile.com/category/events/
Katakanlah kita memiliki halaman A dan halaman B, ini adalah perintah bongkar / muat:
halaman B - acara pagebeforecreate
halaman B - pagecreate acara
halaman B - pageinit acara
halaman A - acara pagebeforehide
halaman A - pageremove event
halaman A - eventhidehide
halaman B - acara pagebeforeshow
halaman B - pageshow acara
Untuk pemahaman acara laman yang lebih baik baca ini:
pagebeforeload
,pageload
danpageloadfailed
dipecat ketika halaman eksternal dimuatpagebeforechange
,pagechange
danpagechangefailed
acara perubahan halaman. Peristiwa ini dipecat ketika pengguna menavigasi antara halaman dalam aplikasi.pagebeforeshow
,pagebeforehide
,pageshow
Danpagehide
adalah halaman peristiwa transisi. Peristiwa ini dipecat sebelum, selama dan setelah transisi dan diberi nama.pagebeforecreate
,pagecreate
danpageinit
untuk inisialisasi halaman.pageremove
dapat dipecat dan kemudian ditangani ketika halaman dihapus dari DOMPemuatan halaman contoh jsFiddle: http://jsfiddle.net/Gajotres/QGnft/
Cegah transisi halaman
Jika karena alasan tertentu transisi halaman perlu dicegah dengan syarat tertentu dapat dilakukan dengan kode ini:
Contoh ini akan berfungsi dalam hal apa pun karena akan memicu permintaan setiap transisi halaman dan yang paling penting itu akan mencegah perubahan halaman sebelum transisi halaman dapat terjadi.
Berikut ini contoh kerjanya:
Cegah beberapa peristiwa mengikat / memicu
jQuery Mobile
bekerja dengan cara yang berbeda dari aplikasi web klasik. Tergantung pada bagaimana Anda berhasil mengikat acara Anda setiap kali Anda mengunjungi beberapa halaman itu akan mengikat acara berulang-ulang. Ini bukan kesalahan, itu hanya bagaimanajQuery Mobile
menangani halaman-halamannya. Misalnya, lihat cuplikan kode ini:Bekerja jsFiddle contoh: http://jsfiddle.net/Gajotres/CCfL4/
Setiap kali Anda mengunjungi halaman acara #index klik akan terikat ke tombol # uji-tombol . Cobalah dengan berpindah dari halaman 1 ke halaman 2 dan kembali beberapa kali. Ada beberapa cara untuk mencegah masalah ini:
Solusi 1
Solusi terbaik akan digunakan
pageinit
untuk mengikat acara. Jika Anda melihat pada dokumentasi resmi Anda akan menemukan bahwapageinit
HANYA akan memicu sekali, sama seperti dokumen siap, jadi tidak ada cara peristiwa akan terikat lagi. Ini adalah solusi terbaik karena Anda tidak memiliki pemrosesan overhead seperti ketika menghapus acara dengan metode mati.Bekerja jsFiddle contoh: http://jsfiddle.net/Gajotres/AAFH8/
Solusi kerja ini dibuat berdasarkan contoh bermasalah sebelumnya.
Solusi 2
Hapus acara sebelum Anda mengikatnya:
Bekerja jsFiddle contoh: http://jsfiddle.net/Gajotres/K8YmG/
Solusi 3
Gunakan pemilih Filter jQuery, seperti ini:
Karena filter acara bukan bagian dari kerangka kerja jQuery resmi, filter ini dapat ditemukan di sini: http://www.codenothing.com/archives/2009/event-filter/
Singkatnya, jika kecepatan adalah perhatian utama Anda maka Solusi 2 jauh lebih baik daripada Solusi 1.
Solusi 4
Yang baru, mungkin yang termudah dari semuanya.
Bekerja jsFiddle contoh: http://jsfiddle.net/Gajotres/Yerv9/
Tnx ke sholsinger untuk solusi ini: http://sholsinger.com/archive/2011/08/prevent-jquery-live-handlers-from-firing-multiple-times/
pageChange acara quirks - memicu dua kali
Terkadang acara pagechange dapat memicu dua kali dan tidak ada hubungannya dengan masalah yang disebutkan sebelumnya.
Alasan acara pagebeforechange terjadi dua kali adalah karena panggilan rekursif di changePage ketika toPage bukan objek DOM yang ditingkatkan jQuery. Rekursi ini berbahaya, karena pengembang diizinkan mengubah toPage dalam acara tersebut. Jika pengembang secara konsisten menetapkan toPage ke string, di dalam event handler pagebeforechange, terlepas dari apakah itu objek atau tidak, loop rekursif tak terbatas akan dihasilkan. Acara pageload melewati halaman baru sebagai properti halaman dari objek data (Ini harus ditambahkan ke dokumentasi, itu tidak terdaftar saat ini). Acara pageload dapat digunakan untuk mengakses halaman yang dimuat.
Dalam beberapa kata ini terjadi karena Anda mengirim parameter tambahan melalui pageChange.
Contoh:
Untuk memperbaiki masalah ini, gunakan setiap peristiwa halaman yang tercantum dalam urutan transisi peristiwa Halaman .
Waktu Ubah Halaman
Seperti disebutkan, ketika Anda mengubah dari satu halaman jQuery Mobile ke yang lain, biasanya melalui mengklik tautan ke halaman jQuery Mobile lain yang sudah ada di DOM, atau dengan secara manual menelepon $ .mobile.changePage, beberapa peristiwa dan tindakan selanjutnya terjadi. Pada tingkat tinggi, tindakan berikut terjadi:
Ini adalah tolok ukur transisi halaman rata-rata:
Pemuatan dan pemrosesan halaman: 3 ms
Peningkatan halaman: 45 ms
Transisi: 604 ms
Total waktu: 670 ms
* Nilai-nilai ini dalam milidetik.
Jadi seperti yang Anda lihat, acara transisi memakan hampir 90% waktu eksekusi.
Manipulasi data / parameter antara transisi halaman
Dimungkinkan untuk mengirim parameter dari satu halaman ke halaman lain selama transisi halaman. Itu bisa dilakukan dengan beberapa cara.
Referensi: https://stackoverflow.com/a/13932240/1848600
Solusi 1:
Anda bisa memberikan nilai dengan changePage:
Dan baca seperti ini:
Contoh :
index.html
second.html
Solusi 2:
Atau Anda dapat membuat objek JavaScript persisten untuk tujuan penyimpanan. Selama Ajax digunakan untuk memuat halaman (dan halaman tidak dimuat ulang dengan cara apa pun) objek itu akan tetap aktif.
Contoh: http://jsfiddle.net/Gajotres/9KKbx/
Solusi 3:
Anda juga dapat mengakses data dari halaman sebelumnya seperti ini:
objek prevPage memegang halaman sebelumnya yang lengkap.
Solusi 4:
Sebagai solusi terakhir kami memiliki implementasi HTML yang bagus dari localStorage. Ini hanya bekerja dengan browser HTML5 (termasuk browser Android dan iOS) tetapi semua data yang disimpan tetap ada melalui penyegaran halaman.
Contoh: http://jsfiddle.net/Gajotres/J9NTr/
Mungkin solusi terbaik tetapi akan gagal di beberapa versi iOS 5.X. Ini adalah kesalahan yang diketahui dengan baik.
Jangan gunakan
.live()
/.bind()
/.delegate()
Saya lupa menyebutkan (dan tnx andleer untuk mengingatkan saya) gunakan on / off untuk acara mengikat / tidak mengikat, hidup / mati dan bind / unbind sudah usang.
Metode .live () dari jQuery dilihat sebagai anugerah ketika diperkenalkan ke API di versi 1.3. Dalam aplikasi jQuery tipikal, ada banyak manipulasi DOM dan bisa sangat membosankan untuk mengait dan melepas kaitan ketika elemen datang dan pergi. The
.live()
Metode memungkinkan untuk menghubungkan sebuah acara untuk kehidupan aplikasi berdasarkan pemilih nya. Bagus bukan? Salah,.live()
metode ini sangat lambat. The.live()
Metode sebenarnya kait acara untuk objek dokumen, yang berarti bahwa acara harus gelembung naik dari elemen yang dihasilkan acara hingga mencapai dokumen. Ini bisa memakan waktu yang luar biasa.Sekarang sudah usang. Orang-orang di tim jQuery tidak lagi merekomendasikan penggunaannya dan saya juga tidak. Meskipun bisa membosankan untuk mengaitkan dan melepas kaitan peristiwa, kode Anda akan jauh lebih cepat tanpa
.live()
metode daripada dengan menggunakannya.Alih-alih
.live()
Anda harus menggunakan.on()
..on()
sekitar 2-3x lebih cepat dari .live () . Lihatlah benchmark mengikat acara ini: http://jsperf.com/jquery-live-vs-delegate-vs-on/34 , semuanya akan menjadi jelas dari sana.Pembandingan:
Ada skrip luar biasa yang dibuat untuk pembandingan acara laman jQuery Mobile . Itu dapat ditemukan di sini: https://github.com/jquery/jquery-mobile/blob/master/tools/page-change-time.js . Tetapi sebelum Anda melakukan sesuatu dengan itu saya menyarankan Anda untuk menghapus
alert
sistem notifikasi (setiap "halaman perubahan" akan menunjukkan kepada Anda data ini dengan menghentikan aplikasi) dan mengubahnyaconsole.log
berfungsi.Pada dasarnya skrip ini akan mencatat semua peristiwa halaman Anda dan jika Anda membaca artikel ini dengan seksama (deskripsi acara halaman), Anda akan tahu berapa banyak waktu yang dihabiskan jQm untuk peningkatan halaman, transisi halaman ....
Catatan akhir
Selalu, dan maksud saya selalu membaca dokumentasi resmi jQuery Mobile . Biasanya akan memberi Anda informasi yang diperlukan, dan tidak seperti beberapa dokumentasi lain yang satu ini cukup baik, dengan cukup penjelasan dan contoh kode.
Perubahan:
sumber
$().live()
didepresiasi di jQuery 1.7 dan dihapus di 1.9 sehingga benar-benar harus menjadi bagian dari solusi jQuery Mobile. Versi inti minimum saat ini untuk jQM 1.7.pagecreate
acara dipecat hanya sekali ketika halaman pertama kali dibuat. jadi jika kita mengikat acara klik di dalamnyapagecreate
itu tidak akan menyala beberapa kali. Sesuatu yang saya temukan saat mengembangkan aplikasi. Tapi kami tidak bisa selalu menggunakanpagecreate
untuk mengikat acara sehingga solusi yang Anda berikan adalah yang terbaik. +1 diberikanBeberapa dari Anda mungkin menemukan ini berguna. Cukup salin tempel ke halaman Anda dan Anda akan mendapatkan urutan di mana acara dipecat di konsol Chrome ( Ctrl+ Shift+ I).
Anda tidak akan melihat bongkar di konsol karena dipecat saat halaman sedang diturunkan (saat Anda menjauh dari halaman). Gunakan seperti ini:
Dan Anda akan melihat apa yang saya maksud.
sumber
Ini cara yang benar:
Untuk mengeksekusi kode yang hanya akan tersedia untuk halaman indeks, kita bisa menggunakan sintaks ini:
sumber
Perbedaan sederhana antara siap dokumen dan acara halaman di jQuery-mobile adalah:
Acara siap dokumen digunakan untuk seluruh halaman HTML,
Ketika ada acara halaman, gunakan untuk menangani acara halaman tertentu:
Anda juga dapat menggunakan dokumen untuk menangani acara pageinit:
sumber
Saat Anda menggunakan .on (), pada dasarnya itu adalah permintaan langsung yang Anda gunakan.
Di sisi lain, .ready (seperti dalam kasus Anda) adalah kueri statis. Saat menggunakannya, Anda dapat memperbarui data secara dinamis dan tidak harus menunggu halaman dimuat. Anda bisa meneruskan nilai-nilai ke dalam database Anda (jika diperlukan) ketika nilai tertentu dimasukkan.
Penggunaan kueri langsung adalah umum dalam formulir di mana kami memasukkan data (akun atau pos atau bahkan komentar).
sumber