I am a little confused over usage of the pageinit
and pageshow
methods in jQuery Mobile. I know that pageinit
is called during initialization and pageshow
is called every time the page is rendered.
I have a home page that loads data using $.ajax()
for some sections. I am loading the data in pageinit
. I am also binding the click and swipe events for pageinit
only. I have also noticed that pageinit
is not called when you come back from another page.
I had one more issue where we are using a carousel using swipe.js
- it does not load properly when using the pageinit
method, but works fine when loading in pageshow
method. What could be the reason for a pageinit
to be called when we use the browser back button?
Also, does caching role any play in deciding where to put the logic of loading data, binding events, etc? It would be best if someone can explain say loading of home page data, then navigating and coming back from another page.
All information found here can also be found in my blog ARTICLE, you will also find working examples.
Lets start from the beginning. As you already know jQuery Developers have provided us with page events to bridge a gap that document ready cant fulfil. While document ready can tell you that content is ready inside a DOM we need more then that because jQuery Mobile still needs to enhance content markup (enhance content style).
There are several page events and every and each of them has its purpose. Some will trigger before page content can be enhanced (like pagebeforecreate) so that dynamic content can be added. Some will trigger only during page change like pagebeforechange.
But let as get back to your question. Pageinit
is here to be a jQuery Mobile version of document ready
. While you can still use document ready
it is still logical to have same alternative among page events.
As you already told you are using pageinit
for event binding (like click or swipe events) and that is a good solution. Mainly because jQuery Mobile
suffers from a problem called "multiple event binding". If e.g. you have a click event bind to an element, nothing can prevent another click event from been bound to the same element. And that will happen if you use pageshow
event. If you use event binding during the pageshow
event, each time page is visited that same event will be bound over and over again. It can be easily prevented but that same prevention will take additional processor processing power, same power that can used to handle rest of web app.
Here we have another question (one of your questions), what is then purpose of pageshow
? Obvious answer would be to do something with a available and shown page. While correct answer it is not that important. Pageshow
is important because it is ONLY page event where page height can be calculated correctly and it is not 0. Now you can see why your carousel needs to be initialized at that point. Carousels like many other plugins (charts, image galleries) requires correct page height and if you initialize them before pageshow
they will have height 0, so they will exist but you will not be able to see them.
Regarding your last question, caching doesn't play a role if your application is built correctly. For a start you should always use delegated event binding because it will not care if page element exist or not. Basically if you bind your event to some parent element like document it doesn't matter if you page is cached or removed from the DOM. As soon as it is back that same event will work again.
Example:
$(document).on('click', '#some-button',function(){
});
This method will bind a click event to document but that same click event will only work on an element with an id 'some-button'
. It really doesn't matter if that element exist or not because document object will always exist.
This same logic is not that important if you work with normal web pages were page reload / refresh is a common thing. Or even here with jQuery Mobile if ajax is turned off so every page change is basically page refresh / reload.
I hope this answers all of your questions. If you need clarifications ask them in comment section.
EDIT :
pageinit
. If you need it each time page is visited then use pagebeforeshow
(because if you use pageshow
that content will just show up out of nowhere and it can confuse the user). Dont use pagebeforecreate
because content will load after the event ends so no point in using it.If you want to load content in some interval use pageinit
with setinterval function. Don't forget to manually enhance page content styles each time dynamic content is added.
Pageshow
is useful only from plugin initialization the requires page height. Nothing else in particular. From answer 1 you can see it is bad for dynamic content because it will show up from nowhere.Pageinit
should be used for event binding and dynamic content generation.