Dynamic jQuery Mobile Pages Without ".live()"
In jQuery 1.7 .live() was deprecated. All good jQuery and jQuery Mobile coders should no longer use it. But how to replace it? .live() was a very powerful way to bind events. Set it once and until the end of your application's life the event was bound. Load new DOM fragments from your server or generate them dynamically in JavaScript and they would have events magically bound to them just like their older brethren.
I don't want to argue whether .live() should have been removed or not, I only want to present a different way to dynamically bind to pages. Until recently I had been using .live() to bind page events in my jQuery Mobile applications framework. Being a good coder I replaced .live() with .on() and promptly broke my code. Everything worked for the internal pages but externally loaded ones no longer got page events.
The Old Way
The old framework relied on .live() to feed all of the page events to the kernel. The code is as follows:
It was a simple as could be. The .live() call hooked all of the desired page events and sent them to the Kernel method. Didn't matter whether the page was loaded or not at the time of the call.
The New Way
The new way isn't as elegant but it isn't hideous either. First I did a bit of clean up. I wasn't using all of the events that I was hooking so I removed the unused ones. I was left with the following events:
pagebeforeshow pageshow pagebeforechange pagechange pagebeforehide pagehide
Then I released that all I needed to know was when a new page was loaded. Once it was I could just use .on() to hook events again. To be safe I would call .off() before calling .on() to be sure that I wasn't double hooking events.
It turns out that when jQuery Mobile loads a new page into the DOM it triggers a pageload event on the document. All I needed to do was to hook it and I was in business.
The biggest change is the addition of the method Rockncoder.Pages.Evs(). It hooks the "pageload" event of the document. When it is trigger it clears all currently hooked page events and then re-hooks them using .on(). Other than a little code clean up that it. The beauty is that it all works dynamically without .live().
As an added bonus I also demonstrate how to dynamically load JavaScript which still works within the framework. Page 2 loads the JavaScript for page 3 if it has not been previously loaded. Then when page 3's link button is clicked it will call via the framework, its event handler code.
RocknCoder.Pages.page2 = (function () {
var pageshow = function () {
alert("page2 show");
},
pagebeforeshow = function () {
// dynamically load the script for page 3
// if it hasn't already been loaded
if (!RocknCoder.Pages.page3) {
$.getScript("scripts/page3.js");
}
alert("page2 beforeshow");
},
That's all for this post. The complete source code is on GitHub.
Source Code for JQM DynamicPages