How to use FastClick with jQuery Mobile the right way?
You don't need to use 3rd party plugins like Fastclick.
jQuery Mobile has already solved this problem with vclick event. It works on desktop and mobile devices and don't have 300ms delay.
Read my other answer if you want to find out more.
$(document).on('vclick', '#someButton', function(){
});
How to use FastClick.js with Phonegap and JQM?
Try with the below code.
function onBodyLoad()
{
document.addEventListener("deviceready", onDeviceReady, false);
}
function onDeviceReady()
{
alert('test');
FastClick.attach(document.body);
}
If everything is fine, you should be able to see the alert box.
Have a look on http://phonegap-tips.com/articles/fast-touch-event-handling-eliminate-click-delay.html
Fastclick interfering with jQuery mobile non-native selects
It seems that when you add class="needsclick" to a non-native select, like this:
<select name="searchPriceto" id="searchPriceto" data-native-menu="false" class="needsclick">
<option value="">Price to</option>
...
then the class 'needsclick' appears rendered in the real select (which is positioned off-screen, hidden away) and in the label text only for the fake select button:
<span class="needsclick">Price to</span>
If your big fat thumb happens to click the text exactly then your non-native menu appears first time, as desired. But if you miss the text and hit the button span, or the parent anchor, or any other parent element then nothing happens, until you try again (for reasons I'm not entirely clear about).
I fixed this by adding 'needsclick' to all the elements in the nest, prior to binding Fastclick like so:
$("#searchPanel .ui-btn-inner").addClass("needsclick");
$("#searchPanel .ui-btn-text").addClass("needsclick");
$("#searchPanel a").addClass("needsclick");
$("#searchPanel select").addClass("needsclick");
as well as having class='needsclick' in the original select tag markup as shown above.
In my original question I was barking up the right tree, but I'd missed one of the elements in the heirarchy (#searchPanel .ui-btn-text) and it seems that this was preventing the fix from working.
I can't help feeling there's a better way than this as it feels a bit hacky, but I thought I'd share it with anyone that has the same problem.
It'd be nice if one could apply Fastclick to only identified elements using a jquery selector :)
Speed Fix: How to Remove the 300ms Delay in jQuery Mobile Apps
I finally found the answer to my speed woes after tireless searching, and it comes in the form of FastClick (this thread goes into great detail, along with some tweaks in the comments from other users).
Incorporate the FastClick.js script, add the onLoad listener, and wrap your <body>
content in a span, and your app should start feeling much more native.
onLoad Listener: <body onLoad="initFastButtons();">
Span Wrap:
<body onLoad="initFastButtons();">
<span id="fastclick">
[...]
</span>
</body>
FastClick.js
//======================================================== FASTCLICK
function FastButton(element, handler) {
this.element = element;
this.handler = handler;
element.addEventListener('touchstart', this, false);
};
FastButton.prototype.handleEvent = function(event) {
switch (event.type) {
case 'touchstart': this.onTouchStart(event); break;
case 'touchmove': this.onTouchMove(event); break;
case 'touchend': this.onClick(event); break;
case 'click': this.onClick(event); break;
}
};
FastButton.prototype.onTouchStart = function(event) {
event.stopPropagation();
this.element.addEventListener('touchend', this, false);
document.body.addEventListener('touchmove', this, false);
this.startX = event.touches[0].clientX;
this.startY = event.touches[0].clientY;
isMoving = false;
};
FastButton.prototype.onTouchMove = function(event) {
if(Math.abs(event.touches[0].clientX - this.startX) > 10 || Math.abs(event.touches[0].clientY - this.startY) > 10) {
this.reset();
}
};
FastButton.prototype.onClick = function(event) {
this.reset();
this.handler(event);
if(event.type == 'touchend') {
preventGhostClick(this.startX, this.startY);
}
};
FastButton.prototype.reset = function() {
this.element.removeEventListener('touchend', this, false);
document.body.removeEventListener('touchmove', this, false);
};
function preventGhostClick(x, y) {
coordinates.push(x, y);
window.setTimeout(gpop, 2500);
};
function gpop() {
coordinates.splice(0, 2);
};
function gonClick(event) {
for(var i = 0; i < coordinates.length; i += 2) {
var x = coordinates[i];
var y = coordinates[i + 1];
if(Math.abs(event.clientX - x) < 25 && Math.abs(event.clientY - y) < 25) {
event.stopPropagation();
event.preventDefault();
}
}
};
document.addEventListener('click', gonClick, true);
var coordinates = [];
function initFastButtons() {
new FastButton(document.getElementById("fastclick"), goSomewhere);
};
function goSomewhere() {
var theTarget = document.elementFromPoint(this.startX, this.startY);
if(theTarget.nodeType == 3) theTarget = theTarget.parentNode;
var theEvent = document.createEvent('MouseEvents');
theEvent.initEvent('click', true, true);
theTarget.dispatchEvent(theEvent);
};
//========================================================
Related Topics
Very Different Font Sizes Across Browsers
Displaying an Element Similar to P Inside a Span
HTML5 Vs HTML4 - H1 Tag Rendered with Extra Space - How to Remove
Performance of Jquery Selectors Vs CSS3 Selectors
Canvas Distorts Drawing. How to Get The Scale Factor Between The Set Size and The Styled Size
Wrapper Question When Containing Floating Divs
How to Keep Text Opacity 100 When Its Parent Container Is Having Opacity of 50
A:Visited Is Not Working on Mozilla But Works Fine on Ie
Set Canvas Element as Background of a Div Element
Ie 10 Bug with Display Table CSS When Height Is 100%
How to Position The Div Popup Dialog to The Center of Browser Screen
Touchmove Pointer-Events: None CSS Doesn't Work on Chrome for Android 4.4/Chromeview
Which Way to Load a Huge Image (Canvas Vs Img Vs Background-Image)
How to Dynamically Size Multi-CSS Sprite Image
Get a Div to Go Across The Whole Page
Force Div Element to Stay in Same Place, When Page Is Scrolled