Posts Tagged projectplace
Use tap events instead of click events in iPhone browser
Posted by Jon in iPhone, Javascript on June 18, 2010
When working on a web app for embedding in a iPhone application we came across jQTouch, a really nifty little jQuery plugin which makes it easy to create a web application UI that really resembles that of a native iPhone application.
We soon encountered a problem due to the fact that click events are rather slow to fire on the iPhone. There is a delay due to the fact that the iPhone waits for the user to complete a gesture before deciding that the intended gesture was in fact a click.
JQTouch uses divs to navigate between screens, so for example if you have the div
<div id="primary-view"></div>
you can simply navigate to it through a normal anchor link, and the transition will thanks to jQTouch be really “iPhone like”.
<a href="#primary-view">Primary view</a>
Our main problem is that we load our content dynamically through Ajax. So our links looked like this:
<a onclick="fetchContent();" href="#primary-view">Primary view</a>
This resulted in a race condition. The anchor link listens to the tap event which is fired much earlier than the click event, and therefore we mostly ended up in empty views. So we needed to replace all onclicks to ontap listeners. The problem then is that we could no longer test our webapp in a normal desktop based Safari browser.
So, we decided to happily go along and write inline onclick events on our links and other interaction elements. But while in the iPhone we see to it that the onClicks are removed and replaced with tap listeners.
That function looks like this:
function rebindClicks(){ var userAgent = navigator.userAgent.toLowerCase(); var isIphone = (userAgent.indexOf('iphone') != -1) ? true : false; if (isIphone) { // For each event with an inline onclick $('[onclick]').each(function() { var onclick = $(this).attr('onclick'); $(this).removeAttr('onclick'); // Remove the onclick attribute $(this).bind("click", preventClickEvent); // See to it that clicks never happen $(this).bind('tap', onclick); // Point taps to the onclick }); } } function preventClickEvent(event) { event.preventDefault(); }
We now call this little function everytime the DOM is changed. If something turns up with an inline onclick. It is will be rerouted by jQuery to a tap listener instead.
Again, we felt we needed to do this because many of our developers do not have a Mac (and hence do not have the iPhone simulator). And testing on the iPhone can be really time consuming. So for testing during development we wanted to use onClick, and when testing on iPhone we wanted to use taps instead.
But the biggest bonus was without a doubt that things are overall much faster in the web application. Taps fire much faster than clicks in the iPhone.
Here’s how it looks running the same app both in desktop safari and embedded into the iPhone simulator.
Submitting iPhone app to App Store
Posted by Samuel in Innovation, iPhone on May 8, 2009
Finally, after two bounces and three weeks of waiting, our first app on App Store is available!
I’ll keep this post really short!
Pros
Cons
Some good to knows!
The App Store review process: 4 stars out of 5Conclusion
If you are curious about our iPhone application, please visit our app section @ App Store.Projectplace for iPhone
DragScrollingCanvas – from the wonderful flexlib
At Projectplace we are currently in the process of developing an exiting thing: a fast and easy to use planning tool (working name: Yap)! You can read more about that at Projectplace Labs.
The reason for this little post however is to promote the open source project flexlib and more specifically a component contained therein, the DragScrollingCanvas. Brad Rice covers the basics of this component.
We’ve had much use of this little component in our early development of our timeline view, and whatever your Flex needs might be, you are sure to find tons of helpful components in flexlib.
One thing that we were lacking was the ability to make some components contained in a DragScrollingCanvas move together with the view port. Basically, we wanted a few components to be able to “float” on top of the Canvas, keeping its relative position at all times. We solved this by dispatching an event from within the DragScrollingCanvas itself. So, first we typed up a little Event (the below event only allows relative positioning vertically).
package com.projectplace.graphics.events { import flash.events.Event; public class DragScrollEvent extends Event { public static const DRAGSCROLLED:String = "dragscrolled"; public var _y:Number; public function DragScrollEvent(type:String, y:Number) { super(type, false); this._y = y; } } }
and within DragScrollingCanvas we dispatched this event as soon as some scrolling occured, in the systemManager_mouseMoveHandler function. Last in this function we added:
dispatchEvent(new DragScrollEvent(DragScrollEvent.DRAGSCROLLED, this.verticalScrollPosition));
This allowed us to be able to listen for the event in the application, and move whatever component within the canvas to a new position on the canvas, while the user is scrolling. If you’re crafty you can easily expand this functionality to the horizontal axis as well. Anyway, this is the result, so far. Notice how the date bar on top, follows your scrolling vertically :)