Reputation: 866
How do you remove the click/tap delay from mobile Safari on iOS?
I have fiddled around with event listeners quite a bit, and have used a bunch of different scripts (such as Lightning Touch) to no joy. There are a few solutions which would have worked, however these types of scripts force you to code a destination element to every link on the DOM. This unfortunately could cause some fast and some slow transitions, which won't work for me.
Upvotes: 16
Views: 19637
Reputation: 813
I am not able to directly post a comment to MikeZ recommendation.
I used it successfully, but had to do some additional tweek, especially for android devices.
Instead of calling event.preventDefault();
in gonClick(), I also had to call event.stopImmediatePropagation();
Otherwise you might run in trouble especially, when dynamic elements, such as panels, are opened on top of the element you clicked.
Complete gonClick() method to be used with MikeZ solution:
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();
event.stopImmediatePropagation();
}
}
};
Upvotes: 0
Reputation: 4943
This is working for me. Whenever a new page is added into the dom, we can then attach fast click to all the links...
// when new pages are loaded into the DOM via JQM AJAX Nav, apply ko bindings to that page's DOM
$(document).on('pageinit', '.ui-page', function (event, data)
{
var activePage = $(event.target).get(0);
FastClick.attach(activePage);
});
Upvotes: 0
Reputation: 19510
Ben Howdle recently created an open source project Touche.js which addresses this problem in a fairly simple and elegant way. Might be worth a look for anyone looking for a solution to this problem.
Upvotes: 0
Reputation: 866
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);
};
//========================================================
Upvotes: 23