8

I've written an html5 application which is supposed to work on mobile devices. 90% of the time it works fine however in certain devices (mostly androids 4.0+) the click events fire twice.

I know why that happens, I'm using iScroll 4 to simulate native scrolling and it handles the events that happen inside the scroll.(line 533 dispatches the event if you're interested) Most of the time it works fine but in certain devices both the iScroll dispatched event and the original onClick event attached to the element are fired, so the click happens twice. I can't find a pattern on which devices this happen so I'm looking for alternatives to prevent double clicks.

I already came up with an ugly fix that solves the problem. I've wrapped all the clicks in a "handleClick" method, that is not allowed to run more often than 200ms. That became really tough to maintain. If I have dynamically generated content it becomes a huge mess and it gets worse when I try to pass objects as parameters.

var preventClick = false;

function handleClick(myFunction){

   if (preventClick)
      return;
   setTimeout(function(){preventClick = true;},200);

   myFunction.call():
}

 function myFunction(){

  ...

 }

<div onclick='handleClick(myfunction)'> click me </div>

I've been trying to find a way to intercept all click events in the whole page, and there somehow work out if the event should be fired or not. Is it possible to do something like that?

Set myFunction on click but before it's called, trigger handleClick()? I'm playing with custom events at the moment, it's looking promising but I'd like to not have to change every event in the whole application.

<div onclick='myfunction()'> click me </div>
Community
  • 1
  • 1
caiocpricci2
  • 7,714
  • 10
  • 56
  • 88

2 Answers2

8

You can do that with the following ( i wouldn't recommend it though):

$('body').on('click', function(event){
  event.preventDefault();
  // your code to handle the clicks
});

This will prevent the default functionality of clicks in your browser, if you want to know the target of the click just use event.target. Refer to this answer for an idea on how to add a click check before the preventDefault();

Community
  • 1
  • 1
Patsy Issa
  • 11,113
  • 4
  • 55
  • 74
  • that would cancel all clicks – SparK Oct 18 '13 at 12:20
  • 2
    @SparK _I've been trying to find a way to intercept all click events in the whole page,_ and it is what the op is looking for. – Patsy Issa Oct 18 '13 at 12:21
  • @Spark That's not true. The events propagate the other way around so first the event fires on my div and after that the event fires on the body. This code prevents everything that is above/outside the body. – caiocpricci2 Oct 18 '13 at 14:32
  • @Patsy Issa thanks for the suggestion but that doesn't solve the problem. – caiocpricci2 Oct 18 '13 at 14:32
  • 1
    It seems that I didn't test it properly and was too quick on my previous comments. I'm not sure if this helps me solving the issue or not but I'll update this post as soon as I find out! – caiocpricci2 Oct 18 '13 at 14:56
  • darn my bad try it with `$(window)` or `$("*")` – Patsy Issa Oct 18 '13 at 14:56
  • @caiocpricci2 To be safe go with window anything clicked will be stopped. – Patsy Issa Oct 18 '13 at 14:57
  • 2
    @PatsyIssa I didn't test your answer properly before commenting. I was wrong. Your solution seems to work very good. assigning it to the body i'm able to intercept every click in the app. I'm still testing on multiple platforms to be 100% sure that there are no side effects but well done! Very good solution! – caiocpricci2 Oct 18 '13 at 15:24
1

I don't like events on attributes, but that's just me.

Thinking jquery: $(selector).click(function(){ <your handler code> } you could do something like:

$(selector).click(function(event){
    handleClick(window[$(this).attr("onclick")]);
};

of course, there wouldn't be any parameters...

SparK
  • 5,181
  • 2
  • 23
  • 32
  • 1
    onclick is an html Event Attribute no it hasn't nor will it ever be (near future) deprecated. – Patsy Issa Oct 18 '13 at 12:27
  • Another problem with this is that there's no guarantee that the element which has the click is an 'a'. It can be an anchor, a div, a list, a span, pretty much anything. – caiocpricci2 Oct 18 '13 at 14:42
  • @PatsyIssa it's just my opinion, sorry if it sounded rude or "official" in any way... – SparK Oct 21 '13 at 18:09