Every mobile web developer knows about the 300ms click delay on iOS devices. It’s a major complaint with HTML5 and hybrid apps. Users expect a responsive app which can not happen with this delay.
Since 2009, there have been numerous libraries to fix this. Matteo Spinelli introduced NoClickDelay back in 2009 (along with a ton of other great HTML5 libraries for iOS). The Financial Times labs also has a good solution. But they all have one major problem.
Ever try an alert or confirm box? There is always a second click that gets triggered, showing the alert/confirm box twice. With jqUi, we overrode window.alert and threw an exception for window.confirm telling them to use $.ui.popup instead…not the best, but we had few complaints.
I finally had time to sit down and look into this again and found the root of the bug. With all the “capturing”, a touch start event is triggered back on the capture layer when the user dismisses the alert/confirm box. Now the browser is sitting there waiting for another touch action on the capture layer to trigger a touch end. It only happens WHEN a touch event is on the capture layer (not outside).
So how can you fix this? There’s no possible way to know if an alert/confirm is going to be called on a click, so we can’t do anything before hand. But since the alert/confirm windows are blocking, we can do a little trickery. Below is a quick overview of the flow/solution for fixing it.
- Create a “skipTouchEnd” variable
- Create a function to return the current milliseconds
- Before we dispatch the click event, get the time
- After we dispatch the click event, get the time
- if the end time - the start time is greater then 100 ms (high threshold, I know), then set skipTouchEnd to true
- in the touchend handler, look to see if skipTouchEnd is true. If it is, set it to false and then return out of the handler, do NOT dispatch another click.
This is a really simple solution, but an odd problem. When developing 1.1, we had tried doing a couple of fixes by setting values in the onclick handler, but never traced it down to the touchstart/touchend dispatching bug.
At the time, jqMobi and jqUi have been patched in github. We are submitting a patch to the Financial Times to fix their FastClick library.
edit - the guys at FTLabs have a better solution using event.identifier (since it’s the same) instead of time stamps.
Right around the time I was starting the work on jqMobi and jqUi (Thanksgiving 2011), I had a chance to play with a Windows Phone 7 at a hackathon in Boston. A Microsoft evangelist, David Isbitski, was showing his phone off and I was impressed. There was one problem though, IE9 wasn’t there.
We released jqMobi and jqUi to target Webkit browsers. jqMobi works fine on any smartphone browser, but jqUi is limitted to Webkit only due to performance issues. Developers (not end users) were asking for support for Firefox and Opera, but no site or framework treats them as an evolved smartphone browser. Chrome on iOS is good, but that is due to the UIWebView shell. FF/Opera on Android still suffered from general Android performance issues.
When Windows 8 previews came out I was impressed with IE10 performance on the desktop. I was fortunate enough to get my hands on a Windows Surface style tablet and found that IE10 still performed great and could support jqUi. My first tests were trying simple animations, like the actionsheet. I replaced the Webkit specific code with the -ms- vendor prefix and it worked fine. So I started porting over each plugin and creating a general $.feat.cssPrefix variable to assist with this.
One great thing about IE10 is that it supports the vendor neutral CSS3 properties, like “transform”, so the style sheets just needed those in addition to -webkit. We added one specific line for Windows Phone 8, and this was a biggie.
What this does is tells the browser to not do anything with the touches and just pass them through. This blocks page scrolling/panning/etc. Special thanks to David Isbitski and his team for being available to help answer questions like this.
While porting jqUi, I uncovered a few bugs that weren’t exposed in Webkit browsers. A big one was not calling .clone() on the default header/footers in the setup code. There were a few other parts where I scratched my head and said “Why did this even work in the first place?”. The code did fail as it should in IE, but Webkit it worked fine.
The full implementaton required genericising all vendor specific CSS properties to use $.feat.cssPrefix and changing the css3 transforms to use $.feat.cssTransformStart and $.feat.cssTransformEnd for translate3d/translate where needed. It’s kinda ugly, but it’s “future” proofing our code base too when more browsers reach the performance we need.
The overall impact to the code is minimal. There were very few additional lines of code we had to add, and most were around CSS3 transforms (the transform end event is different). We also changed our guidelines for developing plugins and code going forward. Look for another post detailing that.
This is the big part of the 1.2 release. We added new functions to jqMobi too, along with properties and helpers. The CSS file and LESS stylesheets have changed too, but if you do not want to support Win8/WP8 your old stylesheets will work fine with 1.2
Pro’s of HTML markup
- Easy for people to learn
- Easy for people to write apps in.
- harder to implement fixes (like iOS no click delay)
- harder to implement “widgets” via CSS.
We are working on jqMobi 1.2 (and 2.0) right now. One of the big changes is the form widgets. We are getting rid of the background images and using CSS. Now, if we were using JSON style programming or iterative markup like jQueryMobile, this would not be an issue. But speed and performance is a factor. So we are left pushing the edges of what can be done.
Developers want to do the following
<input type=’checkbox’ value=’1’ id=’agree’><label for=’agree’>Agree to TOS</label
What they do not want to do is
So what we have to do is find solutions that work with “regular” html markup that users would expect. It’s tough, but it’s fun!
When you change a div’s overflow to “hidden” when -webkit-overflow-scrolling:touch is set, it causes the div to flicker. View it here on iOS6
I finally had time to sit down and look into why iOS6 had a flicker with transitions. It only happened when you went “back”, but it looked ugly. iOS5 did not have this and it looked smooth.
I spent time going through the css3 library trying to see if that was the problem, but could not replicate the issue. I turned off the transition and it still happened. So then I started tracing through (debugMobi was helpful) and found out the issue was with our native scroller’s “enable” function.
With our scrolling library, we allow devs to enable/disable scrolling. This is useful to prevent memory issues with the JS scroller, but we use it internally in jqMobi. I pulled out the css and created basic tests cases until I could replicate it.
jqMobi 1.1 has been released. You can get the code from Github.
See the press release for more info
The first release candidate for jqMobi 1.1 is available in the downloads section at Github. See below for notes from the “Changelog.txt” file.
This is *NOT* a drop in upgrade. There are core CSS file changes for iOS native scrolling, so please do a merge/test locally before deploying.
1) Native scrolling in iOS 5+
2) Chinese keyboard fixes for Android
3) JS scroller written/optimized
4) $().html() now has a second parameter “cleanup” that will dispatch a “destroy” event on notes (memory management). jqUi uses this internally.
5) new $().asap() function for executing code instead of setTimeout
6) $.bind/$.trigger - bind and trigger events on JS objects instead of DOM nodes.
7) touchLayer plugin - handles touch event dispatching and fixes for iOS and Android browsers. This includes fast click and native scrolling/panning.
I just uploaded the 1.03 release. There were a lot of minor bug fixes from the 1.02 series sitting in the main github repo, but people were looking for an official download with those.
edit - We are seeing different problems across different installs. iOS 4.3.2 (iPad 1) has problems that iOS 5 doesn’t have…while 5.1 has issues 5.0 doesn’t have. Some are bugs in the UIWebView, but others are due to Chrome. We have not seen problems like this in Safari across different versions.
We were surprised to see Chrome for iOS. We knew that since apple restricts you to use the UIWebView, you do not get access to the Nitro JS engine. At appMobi, we had released our own mobiUs browser that included DirectCanvas acceleration to speed up canvas games and offer better HTML5 support then safari.
We’ve seen a few bug reports about problems with jqMobi working in Chrome on iOS. After doing a few tests, we’ve found they are problems with the Chrome app itself. We’ve never experienced these problems in a UIWebview using tools like appMobi or Phonegap. Below are three main issues.
- Orientation change event does not get fired. You must listen for “resize”, but that gets triggered on other events
- CSS3 Animations are really buggy. Sometimes panels jump around on pages or transitions are delayed. We think we have a fix for this in 1.1
- Layering/z-indexing issues. There seem to be problems with elements being layered on top of each other, even though z-indexing is set properly and in fact widths/positioning should not be on top of each other
We will examine ways to offer patches, but are worried that these core bugs will create additional issues inside jqMobi and jqUi.
We are getting really excited to launch a beta of 1.1 very soon. The big difference is we’ve been developing apps against 1.1 already, so it’s going through a heavy Q/A cycle. We did the initial development of the branch, and then “tested” it in real life. We found it was a much better scenario, as we were identifying and fixing bugs you could only find from high level usage.
Keep an eye out, but we hope to have it ready in the next few weeks.
We’ve been using jqMobi a bunch at appMobi. We’ve had a lot of bug fixes and new features added, but at the same time we’ve tried to slow down development and let the framework mature.
In the meantime, we’ve also been working on 1.1, which has been led by another group. The update will bring major improvements in scrolling, with native scrolling in iOS5 and fixes for Android and forms. There are new plugins for people who do not want to use jqUi.
We hope to have it released in 2-3 weeks. We’re in the final stages of testing, we just need to update documentation and tie up a few loose ends. But trust us, the 1.1 release will make jqMobi/jqUi the framework to use for building mobile apps!