7

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.

SharpC
  • 6,974
  • 4
  • 45
  • 40
user694688
  • 593
  • 1
  • 15
  • 32
  • Gajotres- I think it is a more specific question because am facing too many issues because of adding some code in pageinit vs pageshow. Have already searched before posting this question. Was not convinced with any answers. Most of them are very generic in the explanation of events. Nothing is said with examples on when to use which event. – user694688 May 25 '13 at 18:36
  • This is nothing personal against you, but I like many other don't want to bother writing an answer if that answer is not going to be accepted, it is simply a waste of time. If I find some spare time I will answer your question. – Gajotres May 25 '13 at 18:48
  • am not getting what you mean to say that the answer is not going to be accepted. – user694688 May 25 '13 at 18:56
  • If you look at a history of question posting you will see that you didn't accepted any answer so far. This tells me that you are not going to accept any answer in a future. When we provide you with an answer we accept something in return, of course if answer is correct. What we expect is an accepted answer or at least an upvote. – Gajotres May 25 '13 at 19:05
  • Really sorry am new to stackoverflow. Had an account but rarely used. After searching came to know only now on how to accept the answer and vote. Am very much sure that whatever you have answered is very useful and clear to me so far. Sorry and thanks. – user694688 May 25 '13 at 19:12
  • Don't worry m8, I hope this answer is what you want. If you have more questions ask them here and I will answer you as best as I can. – Gajotres May 25 '13 at 19:45

1 Answers1

30

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.
SharpC
  • 6,974
  • 4
  • 45
  • 40
Gajotres
  • 57,309
  • 16
  • 102
  • 130
  • Great explanation.Still need a few clarifications. 1. Where should loading of data for a page say using $(ajax) be :pageinit vs pagebeforecreate vs pagecreate. 2. Other than the scenario mentioned above where the page height calculation can be done only during pageshow. Is there any other case where we should use only pageshow. I think it would be great if we can have a table where we say what is the best page event to do a specific operation like loading of data, binding events, etc.., Will be useful to all.Thanks again. – user694688 May 25 '13 at 20:55
  • I have added new content to my answer, so take a look. – Gajotres May 25 '13 at 21:09
  • 1
    Awesome. Am 100% sure that we cannot get this explanation anywhere on net except from your answer. Looking forward for the use cases. – user694688 May 25 '13 at 21:40
  • Superb answer, it gives me all I want – sij Sep 06 '13 at 09:58
  • Just note that `pageinit` has apparently been replaced by `pagecreate` - [jQM API](http://api.jquerymobile.com/pageinit/) – demaniak Mar 17 '14 at 20:40
  • Very descriptive explanation, I wish more like this one; too bad that official documentation isn't so descriptive. Gladly voted up. – Ludus H Feb 23 '18 at 13:19