I'm developing an app, testing on my desktop and mobile. I am trying to fix these slow button presses on the mobile, and just learned about the difference between touchstart and click.
So I bound my buttons with jquery to perform both touchstart and click like so:
$('.button').on('touchstart click', function(){
});
Now the app is performing slightly better on the phone. However, it is performing a touch click, and then a regular click, ie potentially double clicks, or when the next slide comes in, it clicks on something there. In my case a form is appearing, and the input field that appears in the space where the button clicked was, is selected. Ghost click.
How can I tell my function that if there is a touch, ignore the click?
Or better yet, is there a way to tell jquery to just acknowledge all 'clicks' as touches?
I would remove the 'click' binding, but then I can't exactly test in my desktop environment so easily.
If you want to do specific stuff for different event types use e.type
$('.button').on('touchstart click', function(e) {
e.preventDefault(); //prevent default behavior
if(e.type == "touchstart") {
// Handle touchstart event.
} else if(e.type == "click") {
// Handle click event.
}
});
Touchstart should happen before click, so I remove the click handler if the event is of type touchstart. This seems to be working nicely for my purposes:
$('.do-popdown').on('click touchstart', handlePopdown);
function handlePopdown(e){
if(e.type == 'touchstart') {
$('.do-popdown').off('click', handlePopdown).click(function(e){
// do nothing
e.stopPropagation();
e.preventDefault();
return false;
});
}
// do my handling...
// and nothing else:
e.stopPropagation();
e.preventDefault();
return false;
}
The e.stopPropagation(); e.preventDefault(); return false;
may be overkill, but I use this on a variety of different elements (<a>
, <div>
, <span>
, <button>
, &c.) and this meets my usual needs.
EDIT: A more general (better?) approach is to create something similar to the familiar .click()
event binder:
jQuery.fn.extend({
clickOrTouch: function(handler) {
return this.each(function() {
var event = ('ontouchstart' in document) ? 'touchstart' : 'click';
$(this).on(event, handler);
});
}
});
This way, only the appropriate event is attached to the selected element(s).
I suppose a more "proper" name would be .touchstartOrClick()
but since it is more or less a replacement for .click()
I decided to start the name with click
.
This can be used just like .click()
. For example, put a button
inside of a div
and run:
$('button').clickOrTouch(doSomething);
$('div').clickOrTouch(doSomething);
function doSomething(e) {
$('body').append(this.tagName + ' ' + e.type + '<br>');
e.stopPropagation();
}
This will show "DIV click" or "BUTTON touchstart" depending on how it is triggered. If this is used on a link, add e.preventDefault()
if needed in your handler.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With