jQuery Mobile - pageinit vs pageshow

user694688 picture user694688 · May 25, 2013 · Viewed 9.2k times · Source

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.

Answer

Gajotres picture Gajotres · May 25, 2013

Intro

All information found here can also be found in my blog ARTICLE, you will also find working examples.

Difference between pageinit and pageshow

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 :

  1. Where should you load you data depends on what do you need to load. If you want to do in only once then use 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.

  1. 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.

  1. Tomorrow I will update my answer with use cases for every page event. I hope this will be enough for you.