Making a Mom-and-pop

Một phần của tài liệu creating mobile apps with jquery mobile (2nd ed ) matthews gliser 2015 02 27 Lập trình Java (Trang 78 - 132)

The previous chapter taught us some valuable lessons about paper prototyping and gave us a solid ground to start our development with. Now, we will take those drawings and turn them into an actual jQuery Mobile (jQM) site that acts responsively and looks unique.

In this chapter, we cover:

Writing a new jQuery Mobile boilerplate A new way of thinking about full site links

Breaking the boilerplate into a configurable server-side PHP template Using alternate icon sets

Custom fonts

Performance optimization tips

Mobile detection and redirection techniques

CuuDuongThanCong.com https://fb.com/tailieudientucntt

Writing a new jQuery Mobile boilerplate

The jQuery Mobile docs have a lot of hidden gems. They make a great starting point but there are actually several ways of doing your base template. There is the single page template, the multipage template, templates with global configuration, and dynamically generated pages.

So, let’s start out with a new jQM single-page boilerplate based on the original single-page template (http://view.jquerymobile.com/1.4.5/demos/pages/). We will evolve this as we move into other chapters so it becomes an all-encompassing template. Following is the basic directory structure we’ll create for this chapter and the files we’ll use:

For now, here is the base HTML; let’s store it in template.html:

<!doctype html>

CuuDuongThanCong.com https://fb.com/tailieudientucntt

<html>

<head>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">

<link rel="stylesheet" href="css/jquery.mobile-1.4.5.css" />

<link rel="stylesheet" href="css/custom.css" />

<script src="js/jquery-1.10.2.js"></script>

<script src="js/jquery.mobile-1.4.5.js"></script>

<title>Boilerplate</title>

</head>

<body>

<div data-role="page">

<div data-role="header">

<h1>Boilerplate</h1>

</div>

<div role="main" class="ui-content">

<p>Page Body content</p>

</div>

<div data-role="footer">

<h4>Footer content</h4>

</div>

<a href="{dynamic location}" class="fullSiteLink" View Full Site</a>

</div>

</body>

</html>

Tip

Downloading the example code

You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book

elsewhere, you can visit http://www.packtpub.com/support and register to have the files e- mailed directly to you.

CuuDuongThanCong.com https://fb.com/tailieudientucntt

CuuDuongThanCong.com https://fb.com/tailieudientucntt

Meta viewport differences

The meta viewport tag is what really makes mobiles, well, mobile! Without it, mobile browsers will assume that it is a desktop site and everything will be small and will require pinch-and-zoom:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">

This meta viewport tag actually prevents pinch-and-zoom actions. Why? It does this

because modern smart phones are now used by more than just the technical elite. I’ve seen people accidentally zoom in, while just trying to tap a link; and they had no idea what they had done, or how to get out of it. Regardless, if you use jQuery Mobile, your users have no need of zooming anyway.

We will need custom styles. There’s no way around it. Even if we use the jQuery Mobile ThemeRoller (http://jquerymobile.com/themeroller/), there’s always something that needs overriding. This is where you put it:

<link rel="stylesheet" href="css/custom.css" />

<script src="js/custom-scripting.js"></script>

Originally mentioned under the section regarding global configuration

(http://api.jquerymobile.com/global-config/), this is where you put your global overrides, as well as any scripts you may want to run, or have available universally:

<a href="{dynamic location}" class="fullSiteLink">View Full Site</a>

Most mobile websites follow the best practice of including a link to the full site. It’s usually in the footer and it usually links to the homepage of the full site. OK, great! The job is done, right? Wrong! The best practice would be better labeled as the industry standard, because there is a better way.

CuuDuongThanCong.com https://fb.com/tailieudientucntt

CuuDuongThanCong.com https://fb.com/tailieudientucntt

Full-site links beyond the industry standard

The industry standard of simply including a full-site link fails to support the user’s mental state. When a user navigates around on the mobile site, they’re giving a pretty clear

indication of what they want to look at. Supporting the user’s mental model, as they transition from mobile to full site, is more tedious, but crafting a good user experience always is.

Picture this. Sally is looking around on our mobile site because she wants to buy from us.

She has actually taken time to surf down or search for the product she wants to see.

However, due to the constraints of mobile, we made a few conscious choices to not put all the information there. We only included the high points that market research showed people really cared about. At this point, she might be a little bit frustrated as she taps on the full-site link to try to get more information. The full-site link was coded the traditional (lazy) way and took her to the root of the full site where she now has to find the product again. Now, she has to do this using pinch-and-zoom, which only adds to the aggravation level. Unless Sally is desperately interested, what’s the chance she’d continue looking on her mobile, and what’s the chance she’d come back to the site from a desktop browser after such a miserable experience?

Instead, picture that same mobile product page having been thoughtfully crafted to point the full-site link at the product page desktop view. This is exactly what we did at my place of employment. Every mobile page was explicitly mapped to its desktop equivalent. The seamless transition was taken to user testing with actual customers and was met with a mix of 50 percent ambivalence, and 50 percent delight. There was certainly surprise on the users’ side because it did violate their expectations, but there was not a single negative reaction. If this does not successfully argue the case for rethinking the way full-site links are traditionally approached, I don’t know what does. Preserve the user’s mental model.

Preserve the contextual relevance.

If the evidence from the user tests does not convince any who doubt, give them a dose of the following philosophy:

Consistency: This approach is consistent within itself. Every full-site link maps to that page on the full site.

Best practices: A practice is only best until a new practice comes along that is better.

If they would rather keep the old best practices, then perhaps they should sell their car, and get a horse and buggy.

Industry standards: Industry standards are the crutch upon which the rest of the world tries to hobble along, while trying not to fall too far behind the innovators.

Good is often the enemy of great. Don’t settle for it.

Violating user’s expectations: If we tell our users that we’re going to send them a free MP3 player, and we send them a 128 GB iPad 4, have we violated their

expectations? Yep! Think they’ll mind? Some expectations are worth violating.

CuuDuongThanCong.com https://fb.com/tailieudientucntt

Let’s consider the flip side. What if the user really did want to go to the desktop version’s starting page? Well, they’re only one step away, because all they have to do now is hit the home button. So, in all likelihood, we will have saved the user several steps of navigation and, at worst, cost them one extra step to get back to the beginning.

It’s the little details that take a product from good to great. This is certainly a little detail, but I challenge you to spend the extra 30 seconds per page to do this part of the job right.

CuuDuongThanCong.com https://fb.com/tailieudientucntt

CuuDuongThanCong.com https://fb.com/tailieudientucntt

The global JavaScript

Thanks to the AJAX navigation and progressive enhancement inherent in jQuery Mobile, there are a lot of different and extra events. Let’s consider the three unique jQuery Mobile events I’ve found most useful. We’re not going to immediately use them, just be aware of them and be sure to read the comments. Follow along by opening /js/global.js and reading the following script:

$(document).on('pagecreate', 'div[data-role="page"]', function(event){

/* Triggered when the page has been created in the DOM (via ajax or other) and after all widgets have had an opportunity to enhance the contained markup. */

});

$(document).on('pagecontainerbeforeshow', 'div[data-role="page"]', function(event){

/* Triggered before the actual transition animation is kicked off. */

});

$(document).on('pagecontainershow', 'div[data-role="page"]', function(event){

/* Triggered after the transition animation has completed. */

});

CuuDuongThanCong.com https://fb.com/tailieudientucntt

CuuDuongThanCong.com https://fb.com/tailieudientucntt

The global CSS

If this is your first exposure to responsive web design, you’ll notice that most of your custom styles will be in the default section. The other sections are for overriding your default styles to tweak for other device widths and resolutions. The Horizontal Tweaks

section is for overriding styles for landscape orientation. The iPad section is geared for tablet resolutions between the 768px parameter and the 1024px parameter. In the HD and

Retina Tweaks section, you will most likely be only overriding background image styles to substitute higher resolution graphics. We’ll soon see examples of these in action, and put what we use into /css/custom.css. In the mean time, just look at the following structures:

/* CSS Document */

/* Default Styles ---*/

/* Horizontal Tweaks ---*/

@media all and (min-width: 480px){

}

/* HD and Retina Tweaks ---*/

@media only screen and (-webkit-min-device-pixel-ratio: 1.2), only screen and (min--moz-device-pixel-ratio: 1.2),

only screen and (min-resolution: 240dpi) { }

/* iPad ---*/

@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) {

}

CuuDuongThanCong.com https://fb.com/tailieudientucntt

CuuDuongThanCong.com https://fb.com/tailieudientucntt

Breaking the HTML into a server-side template

Normally, I’m a Java guy, but I’ve chosen Hypertext Preprocessor (PHP) due to the prevalence of the Linux, Apache, MySQL, PHP (LAMP) platform. All we’re really doing here is using variables and Server Side Includes to give our templates consistency and flexibility.

Let’s break down the initial HTML into a nice PHP boilerplate. If you want to save this to a file for now, may I suggest the /boilerplate.php file:

<?php

/* the document title in the <head> */

$documentTitle = "jQuery Mobile PHP Boilerplate";

/* Left link of the header bar *

* NOTE: If you set $headerLeftLinkText = 'Back' then it will become a back button, in which case, no other field for $headerLeft need be defined.

*/

$headerLeftHref = "/";

$headerLeftLinkText = "Home";

$headerLeftIcon = "home";

/* The title text which shows up in the header bar */

$headerTitle = "Boilerplate";

/* Right link of the header bar */

$headerRightHref = "tel:8165557438";

$headerRightLinkText = "Call";

$headerRightIcon = "grid";

/* The href to the full-site link */

$fullSiteLinkHref = "/";

?>

<!doctype html>

<html>

<head>

<?php include "includes/meta.php" ?>

</head>

<body>

<div data-role="page">

<?php include "includes/header.php" ?>

<div role="main" class="ui-content">

<p>Page Body content</p>

</div>

<?php include "includes/footer.php" ?>

</div>

CuuDuongThanCong.com https://fb.com/tailieudientucntt

</body>

</html>

Now we’ll extract most of the header and put it into the /includes/meta.php file:

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">

<link href='http://fonts.googleapis.com/css?family=Ubuntu+Condensed' rel='stylesheet' type='text/css'>

<link href='http://fonts.googleapis.com/css?family=Marvel' rel='stylesheet' type='text/css'>

<link href='http://fonts.googleapis.com/css?family=Marvel|Delius+Unicase' rel='stylesheet' type='text/css'>

<link rel="stylesheet" href="css/jquery.mobile-1.4.5.css" />

<link rel="stylesheet" href="css/custom.css" />

<script src="js/jquery-1.10.2.js"></script>

<!-- from https://raw.github.com/carhartl/jquery- cookie/master/jquery.cookie.js-->

<script src="js/jquery.cookie.js"></script>

<script src="js/global.js"></script>

<script src="js/jquery.mobile-1.4.5.js"></script>

<title><?=$documentTitle?></title>

Note

Have a look at the cookies plugin in JavaScript / jquery.cookie.js. You’ll want to download this from https://github.com/carhartl/jquery-cookie. We’ll use it later in mobile detection.

Now, let’s take the page header, make it dynamic, and drop the contents into the

/includes/header.php file, as shown here:

<div data-role="header">

<?php if(strtoupper ($headerLeftLinkText) == "BACK"){?>

<a data-icon="arrow-l" href="javascript://" data-rel="back"><?

=$headerLeftLinkText?></a>

<?php } else if($headerLeftHref != ""){ ?>

<a <?php if($headerLeftIcon != ""){ ?>

data-icon="<?=$headerLeftIcon ?>"

<? } ?>

href="<?=$headerLeftHref?>"><?=$headerLeftLinkText?></a>

<?php } ?>

<h1><?=$headerTitle ?></h1>

<?php if($headerRightHref != ""){ ?>

<a <?php if($headerRightIcon != ""){ ?>

data-icon="<?=$headerRightIcon ?>" data-iconpos="right"

<? } ?>

href="<?=$headerRightHref?>"><?=$headerRightLinkText?></a>

<?php } ?>

</div><!-- /header -->

Next, let’s take the footer content and extract it into the /includes/footer.php file, as shown in the following code:

<div data-role="footer">

CuuDuongThanCong.com https://fb.com/tailieudientucntt

<h4>Call Us: <a href="+18167816500">(816) 781-6500</a></h4>

</div><!-- /footer -->

<p class="fullSite">

<a class="fullSiteLink" rel="external" href="<?=$fullSiteLinkHref?

>">View Full Site</a>

</p>

The header and footer PHP files are set-and-forget files. All we have to do is fill in a few variables on the main page and the meta.php, header.php, and footer.php files will take care of the rest. The headers.php file is coded such that, if your $headerLeftLinkText

tag is set to the Back word regardless of casing, it will turn the left side button of the header into a Back button.

CuuDuongThanCong.com https://fb.com/tailieudientucntt

CuuDuongThanCong.com https://fb.com/tailieudientucntt

What we need to create our site

We have a viable boilerplate. We have a customer. Let’s get to work and code what we drew in Chapter 1, Prototyping jQuery Mobile. For this chapter, we’ll stick to just the home screen to learn the core concepts:

Here’s what we need to think about:

Logo: We’ll simply include the logo from the desktop view.

CuuDuongThanCong.com https://fb.com/tailieudientucntt

Buttons: There are several ways we could accomplish this. At first glance, we might think about using standard data-role="button" links. We could leverage a ui-grid (http://demos.jquerymobile.com/1.4.5/grids/) to add the formatting. If we were only intending to optimize for phones held vertically, this would be a great approach.

However, we’re going to think outside the box here and create a responsive menu that will react well at different resolutions.

Icons: These are not standard jQuery Mobile icons. There are countless icon sets online that we could use, but let’s go with Glyphish (http://glyphish.com/). They make high quality icons that include multiple sizes, retina display optimizations, and the original Adobe Illustrator files just in case you want to tweak them. It’s an

excellent value.

Customer testimonials: This looks like it would be perfectly suited to a list-view, with images. We’ll pull this content from their Facebook page.

CuuDuongThanCong.com https://fb.com/tailieudientucntt

CuuDuongThanCong.com https://fb.com/tailieudientucntt

Getting Glyphish and defining custom icons

Glyphish has a license that allows for free use with attribution. The free set

(http://www.glyphish.com/download/) has only one size and 200 icons, the Pro set has multiple sizes, 400 icons, and an unlimited license. (For only $25 dollars, that’s a no- brainer.)

Creating a button with an icon is simple:

Adding the data-icon attribute will yield a button as shown in the preceding figure:

<a href="index.html" data-role="button"

data-icon="delete">Delete</a>

Whatever you insert as the value for the data-icon attribute will become a class name on the button. If you have an attribute of data-icon="directions", then the class that is applied by jQM is ui-icon-directions. Naturally, you’ll need to craft this in your own custom Cascading Style Sheets (CSS) file as shown in the following code (we’ll put this, and others like it, into the css/custom.css file):

.ui-icon-directions{

background-image:

url(../icons/icons-gray/113-navigation.png);

height:28px;

width:28px;

background-size:28px 28px;

margin-left: -14px !important;

}

We’ll need to get rid of the colored disk around the typical icons. jQuery Mobile has an optional class which takes care of this for you. Add the ui-nodisc-icon class to each link to remove the colored background.

jQuery Mobile masks icons with a circular border. This works well for smaller icons, but for larger ones, we’ll need to remove the mask. To do this, we’ll add a glyphishIcon class to each link we want to customize, in this fashion:

CuuDuongThanCong.com https://fb.com/tailieudientucntt

We’ll also need to add this definition to our custom.css file:

.glyphishIcon:after { height: 28px;

-moz-border-radius: 0px;

-webkit-border-radius: 0px;

border-radius: 0px;

}

In the end, our code for the four buttons on the front page would look as follows:

<div class="homeMenu">

<a class="glyphishIcon ui-nodisc-icon" data-role="button" data- icon="directions" data-inline="true" data-iconpos="top"

href="http://maps.google.com/maps?q=9771+N+Cedar+Ave,+Kansas+City, +MO+64157&hl=en&sll=39.20525,-

94.526954&sspn=0.014499,0.033002&hnear=9771+N+Cedar+Ave,+Kansas+Ci ty,+Missouri+64157&t=m&z=17&iwloc=A">Map it</a>

<a class="glyphishIcon ui-nodisc-icon" data-

role="button" data-icon="iphone" data-inline="true" data-iconpos="top"

href="tel:+18167816500">Call Us</a>

<a class="glyphishIcon ui-nodisc-icon" data-role="button" data- icon="facebook" data-inline="true" data-iconpos="top"

href="https://touch.facebook.com/nickyspizzanickyspizza">Like Us</a>

<a class="glyphishIcon ui-nodisc-icon" data-role="button" data- icon="utensils" data-inline="true" data-iconpos="top" rel="external"

href="menu.php">Menu</a>

</div>

It would be rendered on the screen, as shown in the following screenshot:

CuuDuongThanCong.com https://fb.com/tailieudientucntt

Một phần của tài liệu creating mobile apps with jquery mobile (2nd ed ) matthews gliser 2015 02 27 Lập trình Java (Trang 78 - 132)

Tải bản đầy đủ (PDF)

(434 trang)