Rusty's Rhythm Club Mobile Website

Create Cheap, Lightweight Mobile Websites for Small Businesses

The current craze in mobile web development is undoubtedly responsive design, i.e., making websites that adapt dynamically to the size of the browser window using CSS liquid layouts and media queries rather than looking at what hardware device is being used.

I am a big fan of responsive website design, but consider the case where your client is a small business that has an existing desktop website for which it paid a lot of money for.  Suppose your client doesn’t want to spend thousands of dollars on a brand new responsive site “just” to make it mobile-friendly.  Are there any cheaper options? Does the mom-and-pop diner down the street have to completely re-do its website every time there is a new craze in mobile web development?

In this article, I’ll discuss methods I’ve developed (and discovered) for creating a lightweight mobile web app that exists alongside a desktop website.  One of the key features of the mobile site is that it will read content from the desktop site so that your client only has to maintain one site. A little warning, this article is for advanced developers, as I will be talking about broad methodologies without going into all of the details.

The Mobile App “Look”

Camp Hollywood Mobile Website

The first requirement is that the site should be easy to navigate on a mobile device and have the general look and feel of a mobile app, without being to anal about it.  If you are reading this, I am assuming you are a web developer who already knows how to make big rectangular buttons with rounded corners, so I’ll somewhat gloss over the details.

Rusty's Rhythm Club Mobile Website

In order to keep the app “lightweight”, I am avoiding mobile frameworks like jQuery Mobile, Sencha Touch, etc.  I found that it doesn’t really take that much CSS to make a mobile-friendly site.  You can roll your own or look at the CSS files in a couple of my mobile sites to see what I’m talking about.  Click the images on either side for examples from two of my sites.

I found that once you’ve done one, making new sites from your initial template is super easy.

Having said that, there are indeed a few tricks to get your site to look more like a native app, especially in iOS.  For example, if the user saves your site to their home screen, you can have a custom splash screen and home screen icon, and make the browser address bar go away.  I did a whole other presentation on making websites look like iOS apps which you can find here.

A good book on this topic is Jonathan Stark’s “Building iPhone Apps with HTML, CSS, and JavaScript”.

The Mobile App “Feel”

If you go to most websites on a mobile device like an iPhone, you’ll notice that the links seem just a bit slower to respond than on a desktop.  Indeed, there is a 300ms delay in iOS browsers from when you tap a link and when it actually starts navigating to the site.  For websites where you don’t navigate much that might be fine, but the delay is actually enough to make your web app seem as slow as molasses compared to a native app.

It turns out that solving this problem is not as easy as it would seem.  Yes, you can use JavaScript to override the click handler, but what if the user just wanted to scroll the page and touched your button in the process?  The page would go to the new link instead of scrolling.  You have to not only detect the tap, but also detect if the user moved his finger during the tap.  The same can be said of pinching and so forth.  It turns out that it’s a real pain to account for all of these cases.

Happily, someone has done this work for us.  Aanand Prasad has created a jQuery plugin that makes taps instantaneous.  You can check it out here: http://aanandprasad.com/articles/jquery-tappable/

If you use this plugin, your navigation will be fast and snappy, just like a native app!

Screen Scraping without Much Coding

OK, let’s get to more meaty issues.  As I mentioned, one of the key features of the mobile site I’m describing is the ability to read a desktop site, “screen scrape” content, and present it in a mobile-friendly way.  That way, your client only has to update his desktop site and magically the mobile site will stay in sync.  You definitely don’t want to make your client update two sites!

Now, depending on your PHP programming ability and the complexity of the site you’re scraping, writing the code from scratch can take a couple of hours or much longer, even if you’re a pretty good programmer.  You’d have to read in the file, parse it, and then look for HTML tags or other keywords using regular expressions, then continue parsing to look for the closing HTML tag or other way to detect the end of the content.  It can be a lot of work.  But, I said these sites would be cheap to develop, and that’s not cheap.

Wouldn’t it be great if there was a way in PHP to grab the HTML contents of a div, just like you can do in JavaScript and jQuery?  Fortunately, there is.  It’s called “PHP Simple HTML DOM Parser”.  You can get it here: http://simplehtmldom.sourceforge.net/

Let’s say there is a div with id “content” that you want to scrape from the client’s desktop site. Save the simple_html_dom.php file to your scripts directory, then add these four lines of code where you want the content delivered in your site:

require('scripts/simple_html_dom.php');
$html = file_get_html('http://www.your_clients_site/index.html');
foreach($html->find('div#content') as $e)
echo $e->innertext;

That’s it!  Four lines of code to screen scrape a file!  No regular expressions.  No parsing.

In my mind, this is one of the key discoveries that makes these mobile web apps affordable to develop.  You don’t need to spend hours coding a screen scraper.  Just find a div tag or other HTML tag that encloses the content you want, grab it, and echo it to your site.

Once you have the content, you can wrap it in your mobile-friendly HTML and CSS and voila, you have a new page based on the content from the desktop site.  Your home page can simply link to these pages with your big buttons.

Or, if you are savvy with AJAX, you can avoid a total page re-load and just load the content.

From what I’ve presented so far, you have the basic tools to make a mobile website that has the look and feel of a mobile web app, and that dynamically reads content from a desktop site, so that no content updating is required.

But, we can still do better.

Making Navigation Even Faster

If you make a mobile website like I’ve described so far, you’ll notice that every time you press a button to go to a new page (or load new AJAX content), the browser has to call the server to make a request.  This takes a few seconds and detracts from the overall snappiness of your mobile site.

We can avoid this by loading all of the pages initially, then hiding the ones we’re not viewing using the CSS.
  After that, button presses will unhide the desired sections, and hide the undesired ones, using jQuery.  You can see how I implemented it here using jQuery:

// handle each of the buttons
$('.button').each(function() {

// make button activation snappy
$(this).tappable(function() {
// hide all pages
$(‘.page_body’).hide();

// show new page using jQuery
new_page=$(this).attr(‘title’);
new_page = ‘#’+new_page;
$(new_page).show();

// store the current URL hash
window.location.hash = new_page;

window.scrollTo(0,1);
return false;
});
});

Note that all of the “pages”, except for the home page, are first hidden in CSS using “display: none;” (not shown here).

The first line finds all elements with the “.button” class attached. The second line of code invokes the .tappable method. In my HTML, all of the pages of my site that are dynamic have the class “.page_body”. Thus, hiding this class hides all of the pages.

Next, I find the title attribute of the button being pressed (you could use the href attribute instead), append a hash to it to make it a class name, then show the div with that class name.

Don’t worry about window.location.hash for now. I’ll explain that later. The window.scrollTo gets rid of the browser bar.

Of course, this will make the web app take longer to load.  But once it’s loaded, navigating will be super fast and the user experience will really mimic that of a native app.  You’ll have to balance the tradeoff between initial load time and fast navigation.  I wouldn’t try to scrape more than five pages on startup, or else it will take too long for your app to load.


That’s Great, Except the Browser Buttons Don’t Work!

Okay, now we have a really snappy mobile web app (I’m calling it a “mobile web app” instead of “mobile website” now.. I think we have earned it).  But, there’s one pretty darn big problem.  Since the entire site is just one page, browser back and forward buttons don’t work.  If the user presses the browser back button, they will exit the app and go to whatever page they were on before.

My first thought was to hijack the browser’s “back” button and deal with the problem that way.  I quickly found out that there are some big difficulties with doing that, not to mention it’s bad practice.

In my research, I did find some plugins that solve this problem for single-page websites like mine.  They were cool, but I resisted loading yet another plugin that would further weigh down my supposedly lightweight site.  Plus, I’d have to learn how to use another interface.

After further investigation, I learned that these plugins rely on a key fact:  JavaScript is able to read and modify the part of the URL after the hash.  For example:

http://mysite.com/#you_can_read_and_modify_this_part

Furthermore, browsers keep track of the entire URL including the hash portion in the browser history.  In other words, if the user presses the browser back button, the hash part of the URL will get updated with whatever it was before.  This might seem obvious, but the implication is huge.  You can implement your own forward/back functionality without having to keep track of browser history yourself.

With these two pieces of information, I was almost ready to roll my own lightweight solution.

Here are the key pieces of JavaScript are reading and writing the hash.  It’s super simple.  You read the hash using this line of code:

my_page = window.location.hash;

You set it using this:

window.location.hash = “#home”

In both cases, the hash symbol is included.  So, if you read the hash of “mysite.com#home”, you’ll get back “#home” (not “home”).  Similarly, if you want to set the hash to “mysite.com#home”, you should set the hash to “#home”.

Also, keep in mind, setting the hash doesn’t initiate and server request or page update.  It just updates the browser address bar.  You have to update the contents yourself.  But that is fine.  In fact, that’s what we want, because we don’t want a server call and you already have code to hide and unhide the proper divs, right?

The final piece I needed was how to detect when the change in hash.  To do this, you need to set up a JavaScript interval timer.  I set mine to check every half second.  This seemed to give the browser back/forward buttons just enough responsiveness without loading down the browser too much.  Here is my code:

// implement browser forward/back buttons by scanning the URL hash
intervalID = window.setInterval(function() {
// check current URL hash
previous_page = window.location.hash;

// if the hash changed, then change page
if (previous_page!==new_page)
{
// make sure we are going to a valid page
if ((previous_page==””)||(previous_page==”#home”)||(previous_page==”#schedule”)||(previous_page==”#contest”)||(previous_page==”#tickets”)||(previous_page==”#location”))
{
// change page
$(‘.page_body’).hide();

// treat no hash as “home”
if (previous_page==””)
$(“#home”).show();
else
$(previous_page).show();

// note, do NOT update the window.location.hash; the browser does that for you.
new_page=previous_page;

window.scrollTo(0,1);
}
}
}, 500);

First, we set up the interval timer.  As I mentioned, I set it to 500ms (in the last line).  Every interval, we read window.location.hash and compare it whatever page we thought we were on.  If it’s different, it means the user either pressed the back button or forward button.

I use the new hash value to “navigate” to (or more accurately, “unhide”) the previous page.  But before doing that, I check to make sure the hash value is valid, since the user could type in anything in the browser address bar.  There is one other caveat here, which is that on initial load, there is no hash.  It’s blank.  If the previous page has no hash, I manually load the home page.  Otherwise, I reveal the page determined by the hash.  Finally, I scroll to 0,1 to eliminate the pesky address bar in mobile browsers (some sources say that certain browsers choke if you navigate to 0,0).

So, with just a few lines of JavaScript, we have enabled complete browser forward and back functionality on our one-page web app!!

If You’re Still Not Satisfied: Offline Storage

There is one more feature that we can add to this app to make it even cooler, namely offline storage.  With that, the user loads the site once, and it is cached locally on his or her device.  After that, no Internet connection is needed to load the site, and it behaves much like a native web app!  The feature is designed such that it will check your files for changes and update if necessary.

I implemented this on my Camp Hollywood app, and it’s pretty cool!  But in that case I did not have access to the desktop site, so I was unable to test it completely.  For that reason, I left this feature off of the production version.

This article is getting long-winded, so I’ll leave the details for you to research, especially since I don’t have production-quality code to show. You can Google how to do it, or again check Jonathan Stark’s book.

The Icing on the Cake: Save to Home Screen Prompt

small_IMG_0445_ios_balloon_promptI want to leave you with one other cool widget which pops up a balloon prompting iOS users to save your web app to their home screen.  It’s called “Add to Home Screen” and you can get it at Cubiq.org.  This is a great way to encourage iPhone and iPad users to save your app.  It looks really professional but I did encounter a few issues.

For one thing, the “dismiss” button never worked for me on iPhone or iPad.  Some other users have reported this too.  So, I just use the version without the dismiss button and make the popup stay on screen for just a few seconds.

Second, there is an “expire” setting which lets you determine the maximum rate that the popup appears, so that it won’t keep popping up and annoying your users every time they visit your site.  But, if you have private browsing set to “ON”, the local storage needed for this feature won’t be available and the widget won’t work at all.  In the end, you have to weigh not having this widget work for people who have private browsing on vs. not using the “expire” setting and risking annoying everyone.

In the End

So, after all of this you should have a very snappy, lightweight mobile website that updates automatically when your client updates his main site.  Once you do one of these, you can really crank them out, making them an inexpensive alternative to a complete site overhaul.

Before I stop I’d like to emphasize that I am all-for responsive website design!  My work on these separate mobile sites came about from customer requests for a cheap mobile web app that didn’t require throwing away their existing site.

Hope this has been helpful!  Let me know if your thoughts on this.  Thanks! – Brian

3 thoughts on “Create Cheap, Lightweight Mobile Websites for Small Businesses

    1. Hi Mickey,

      Thanks for your question! Yes, it should do fine with SEO, with the caveat that the entire website is on a single “page”. That is, all of the pages of the mobile site are loaded at one time and are simply hidden or shown using JavaScript. So, search engines might not differentiate these pages, but all of the content will be readable by search engines, which I think is the main thing.

      Thanks,
      Brian

Leave a Comment or Ask a Question