Book Image

PhoneGap 3.x Mobile Application Development HOTSHOT

By : Kerri Shotts
Book Image

PhoneGap 3.x Mobile Application Development HOTSHOT

By: Kerri Shotts

Overview of this book

<p>PhoneGap allows you to use your existing knowledge of HTML, CSS, and JavaScript to create useful and exciting mobile applications.<br /><br />This book will present you with 12 exciting projects that will introduce you to the dynamic world of app development in PhoneGap. Starting with their design and following through to their completion, you will develop real-world mobile applications. Each app uses a combination of core PhoneGap technologies, plugins, and various frameworks covering the necessary concepts you can use to create many more great apps for mobile devices.</p>
Table of Contents (21 chapters)
PhoneGap 3.x Mobile Application Development HOTSHOT
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Tips


These tips are things I've encountered while working on this book and while writing other Cordova/PhoneGap apps. There's no real common theme here, but it might help save you a few minutes should you encounter the same problem in the future.

Prevent highlighting and outlines when tapping

Mobile browsers are not like desktop browsers. This may sound obvious at first glance, but mobile browsers have to deal with large, squishy fingers, whereas most desktops still use mice or trackpads which have much greater accuracy. This means that it is easier to tap on the wrong item when using a mobile browser. It can also be more difficult to know when a tap has been registered.

To accommodate this profound difference between mobile and desktop browsers, mobile browsers offer affordances to users so that they know that, yes, their tap was registered, and that this is what they tapped. This is usually done by highlighting the element with a specific color or outlining the element in a color, or both.

While it is important for native apps to have affordances, the browser doesn't typically render the affordance in the way the user would like. Some of this can be changed (the color can be modified, for example), but more often than not, the affordance rendered by the browser does not match the designer's vision.

There is a fix, however, to disable these browser-driven affordances. Remember, though, that you should provide your own affordances when applicable if you turn these browser affordances off globally.

These rules can disable both the highlight and outline affordances. Remember to add the browser prefixes in your code as follows:

tap-highlight-color: rgba(0,0,0,0);
tap-highlight-color: transparent;
outline: none;

To apply these rules globally, you can attach them to the body element in your CSS. For most native apps, this is what you'll generally want.

Note

The transparent rule is for some Android devices. See http://phonegap-tips.com/articles/essential-phonegap-css-webkit-tap-highlight-color.html.

Include affordances

Now that we've essentially removed all the affordances provided by the browser, we need to add some back for the sake of user experience. Generally, these include changing the text or background color of buttons and list items.

As long as the item in question has an event handler registered that uses a touchstart event, you can create CSS rules using the active pseudo-element as follows:

.ui-list-item:active {
  background-color: blue;
}

Prevent unwanted text selection

Native interfaces generally don't allow users to include user-interface widgets inside selections. By default, however, the mobile browser used by Cordova/PhoneGap will permit this, resulting in a decidedly odd experience.

To turn it off globally, attach the following to the body element:

  user-select: none;

For elements that need to support selection (such as actual content or text inputs), replace none with text.

Improve text rendering

By default, the mobile browser renders text fairly poorly; it doesn't support ligatures, kerning, or the like. However, you can enable this feature to use better typography in the app (for fonts that support it). Again, attach to the body element as follows:

text-rendering: optimizeLegibility;

That said, this shouldn't be used on Android devices, since some versions don't calculate the text boundaries correctly. For Android, turn it back off as follows:

body.android {
  text-rendering: auto !important;
}

Use native scrolling

On a desktop, one would typically use overflow: scroll or overflow: auto to make certain elements scrollable. This works to a degree on most mobile devices, but the experience is decidedly non-native on iOS. For example, there may not be inertial scrolling or rubber-banding effects.

To enable this on iOS 5 and above, add the following to any scrollable container:

-webkit-overflow-scrolling: touch;

Keep in mind that native scrolling of this form works only on iOS 5 and higher. It doesn't hurt to use the property on Android devices (or any WebKit browser) since if the browser doesn't know what to do with it, it will ignore the property.

Tip

If Android is not using native scrolling, try this:

For Android platforms, adding a z-index to the scrollable area may trigger native-feeling scrolling if Android wasn't applying it before. It's possible anything that creates a new stacking context may also force the issue (so position:absolute may also work).

Use a scrolling library

If you can't use native scrolling or need to support a platform where you need to offer a fallback, use a scrolling library.

There are several available, but I can't recommend iScroll enough, it's not perfect (no scrolling library ever is), but it's the closest I've seen and supports a wide variety of platforms. You can get it at https://github.com/cubiq/iscroll.

Use 3D transforms to use the GPU

When you add a 3D transform to an element, it will use the GPU to composite the element instead of the software renderer. This can improve performance during animations and scrolling, but it does come at a cost: memory. This works best on items that aren't more than four times (or so) the size of the screen—more than this may cause visual artifacts (as the GPU must use tiling to draw the element).

There are a couple of methods you can use. The first one is as follows:

  transform: translateZ(0);

Alternatively, you can use:

  transform: translate3d(0,0,0);

When using 3D transforms, hide the backface

You may notice that elements flicker when using the GPU. If this is the case, hide the back face:

  backface-visibility: hidden;

Remember perspective while using the GPU

Even though 3D transforms don't automatically default to rendering elements with perspective like in a 3D game, perspective itself is still used. This means that when animating elements over each other, it's possible that you may see elements being rendered in the wrong order. Your first instinct will be to add z-index, which is fine for non-GPU elements, but it won't do anything when using the GPU. Instead, use a specific z-value to ensure that the element renders closer to the user than those behind it. For example, consider the following code snippet:

  z-index:9;
  transform: translateZ(9px);

The z-index here has no specific save function to make it clear that this element is intended to render above other elements. The actual work, however, is accomplished by the translateZ(9px) portion—this renders the element 9px closer to the user's view than other elements. Since there's no perspective, there's no apparent change in size as elements move along the z( )axis, so the user doesn't notice, but the browser rendering engine surely does.

Use click prevention or prevent default actions

It's possible that you may encounter what seem to be spurious events occurring immediately after a tap (or other gesture) that invokes a navigation animation. There are a couple ways around this:

  • Use a "click prevention" DIV: This DIV is put up prior to the animation once the gesture is detected and is removed from the DIV after the navigation is complete. This DIV is told to fill the entire screen and is transparent, so the user never sees it, but the DOM won't pass events below it. If you inspect YASMF's Navigation Controller, you'll notice that it throws up a click prevention DIV during a view navigation animation for this very reason.

  • Prevent the default browser action: This works as well, if not better, than the prior, since it doesn't involve manipulating the DOM. Hammer.js makes this really easy to do—one can enable it by passing prevent_default:true as an option, as shown in the following code:

    Hammer(contentsElement, { prevent_default:true }).on("tap", function (e) {} _;

Complex effects hinder performance

Although most modern devices come with powerful GPUs, this hasn't always been the case. Even with GPUs, it's still pretty easy to bog down the compositor so that performance lags and stalls.

There's no one-size-fits-all fix to handle this, though. Here are some general pointers, however:

  • Avoid using gradients: The gradients take time to compute.

  • Avoid scaling images: The interpolation of an image is painfully slow.

  • Avoid shadows: These require underlying elements to be composited first, and then the shadow to be composited on top. This takes time. Additionally, any blur in the shadow has to be calculated.

  • Avoid partial transparency: Like shadows, this requires composition. It's a little faster, since the shadow blur doesn't have to be calculated.

  • Avoid rounded corners: Creating rounded corners requires computations.

  • Avoid a lot of elements in the DOM: The more the elements in the DOM that have events or need to be positioned by the browser, the slower things run due to the required calculations. This means that you shouldn't ever attach an event handler to a DOM element that doesn't need it (even if it does something cool), and you should limit the amount of positioning calculations the browser has to go through.

Audio/video file extensions matter

Although one would hope that things have progressed to the point where the file type could be inferred from the file itself, we're still sadly stuck with the fact that file extensions matter. Therefore, don't create a video file with a .video extension, or an audio file with a .audio extension. This will fail, simply because the extension is important in determining how to parse the file.

Instead, use the proper file extensions. The extensions we used in this book are as follows:

Platform

Audio

Video

Android

.3gp

.3gp

iOS

.wav

.mov

Careful with XHR/AJAX status values

When working with XHR status values, especially when dealing with content on the local filesystem, be sure to handle both 0 and 200 return values. Different platforms return different values for a successful operation.