44

When I use jQuery for a simple click event it only works for links. Is there a way to make it work for spans etc:

$("span.clicked").live("click", function(e){alert("span clicked!")});

$("a.clicked").live("click", function(e){alert("link clicked!")});

The SPAN works in Safari but not Mobile Safari (on iPhone or iPad) whereas the A tag works in both.

Gazzer
  • 4,524
  • 10
  • 39
  • 49
  • I think the answer should be changed to https://stackoverflow.com/a/4910962/16940 by Plynx and not the current answer from Sam. Plynx's answer definitely has the votes and the support. – cdpalmer Sep 14 '18 at 17:14

8 Answers8

130

I struggled with this as well. After lots of toying around and trying to figure out the problem, I came across a simple solution.

If you set the element's cursor to pointer, it magically works again with Jquery's live and the click event. This can just be set globally in the CSS.

Plynx
  • 11,341
  • 3
  • 32
  • 33
  • 1
    Been searching for a fix like this for months thanks. I has come up with iphone/pod/pad detection and changing click events to other events just for those devices. This is much better. – danmayer Nov 29 '11 at 16:02
  • 6
    note that it won't work if you do `cursor: pointer;` on hover. – pseudosudo Apr 01 '13 at 21:23
  • @pseudosudo can you elaborate? there's no hover on a ipad - or are you talking about this breaking desktop versions in some respect, or 'Samsung hover on Galaxy S4' ? – Simon_Weaver Jul 05 '13 at 13:53
  • 3
    @Simon_Weaver `div:hover { cursor: pointer; }` doesn't work, just do `div { cursor: pointer; }` – pseudosudo Jul 06 '13 at 21:31
  • CSS `Cursor:Pointer;` is a great solution. **FastClick** https://github.com/ftlabs/fastclick is another solution. – Milk Man Aug 27 '14 at 23:00
  • this had the added bonus that a hand icon is shown for desktop users - useful if your element isn't obviously clickable. also when using `touch` events alone they are triggered *immediately* on touch which can conflict with a simple scrolling action. – Simon_Weaver May 26 '17 at 04:18
  • This is the correct answer- register click event as usual on any DOM element, and make sure cursor: pointer is set in css, but not on hover. – Joshua Harris Jun 06 '18 at 01:54
28

You need to listen for the "touchstart" and "touchend" events. Add the listeners with jQuery...

$('span').bind( "touchstart", function(e){alert('Span Clicked!')} );

You may wish to listen for a touchstart and touchend so that you can verify that the element targeted when the finger touched is the same as the element targeted when the finger was removed.

I'm sure there is probably a better way to do it but that should work :)

Edit: There is a better way! See https://stackoverflow.com/a/4910962/16940

Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
Sam
  • 563
  • 4
  • 9
  • Thanks. Does this mean that iPhone ignores click events except to links (perhaps because of the other possible gestures) ? – Gazzer Jun 12 '10 at 06:40
  • I think that because tags work the way they do i.e. they're there to be clicked - mobile webkit handles the click event on them automatically. I don't know this for sure. It's just an assumption – Sam Jun 14 '10 at 20:43
  • You are missing a closing parenthesis. Should be $('span').bind( "touchstart", function(e){alert('Span Clicked!')}); – mhenry1384 Jul 17 '12 at 19:09
  • 1
    Thanks, this is working for spans, divs and buttons but not for image tag.. Please suggest – User16119012 Sep 02 '13 at 17:05
  • 4
    NO NO NO NO (almost certainly) - see @Plynx's answer – Simon_Weaver Sep 16 '14 at 15:30
  • @Simon_Weaver Okay, Plynx' may also work, but this answer also appears to solve things acceptably in my use case today. What's the weakness? How could Sam's answer be better? Is there a danger to using `touchstart`? Or do you just feel the other answer is a cleaner solution (and why)? – ruffin May 25 '17 at 19:20
  • @ruffin If you use 'touchstart' then it will trigger your event *immediately*. this includes when the user scrolls up the screen and just touches your 'span' by mistake. people expect to scroll by touching any part of the screen without it triggering a click - ever scrolled a page and had an ad popup? annoying isn't it! plus it just isn't necessary when you use the `pointer: cursor` css and that has the added benefit of showing a hand icon for desktop users. when using touch' events it is good idea to consider using a library because there are added complexities for devices with pen + touch. – Simon_Weaver May 26 '17 at 04:15
  • also - and I'm not completely sure about this but on iOS certain actions can only be performed when there is a real click - for security reasons. I believe that touch events don't 'count' in this case. eg. for playing a video on an iPhone you need a click and you can't auto-play – Simon_Weaver May 26 '17 at 04:20
21

You actually don't need to use the touchstart or touchend event, so long as the 'span' tag (or anything other than an 'a' tag) has a css property of:

cursor:pointer

the click will register

MonOve
  • 1,091
  • 13
  • 34
2

You can also coax the browser to generate click events by adding an empty onclick attribute. For a belt-and-braces approach in case either approach stops working in any given iOS update, you could use something like this:

$("span.clicked").live("click", function(e){alert("span clicked!")})
                 .attr('onclick','')
                 .css('cursor','pointer');

(assuming you don't have any actual onclick attributes you don't mind obliterating)

CupawnTae
  • 14,192
  • 3
  • 29
  • 60
2

You can add an empty onclick attribute, like so:

<span onclick=''>Touch or Click Me</span>
jQuery('span').live('click', function() { alert('foo'); });
Charlie Schliesser
  • 7,851
  • 4
  • 46
  • 76
1

I tried everything and none of the tricks worked. It turned out I couldn't get click events because I had a video element under my img. video elements apparently eat click events.

mhenry1384
  • 7,538
  • 5
  • 55
  • 74
1

When targeting iOS you have to take the following into consideration: doing event delegation in jQuery like $(document).on('click', '.target-element', function (event) {...}); will not work. You have to add either onclick="" to the target HTML element or cursor: pointer to its styles.

Taken and adapted from http://gravitydept.com/blog/js-click-event-bubbling-on-ios:

It turns out that Safari on the iPhone does not support event delegation for click events, unless the click takes place on a link or input. Fortunately there are workarounds available.

That's the reason while the <a> tag works while <span> doesn't.

mcdado
  • 718
  • 1
  • 8
  • 15
0

My approach to solve this misunderstanding on document.click.

  1. Add into html after tag body next tag

    <body> <div id="overlaySection" onclick="void(0)"></div> ... </body>

  2. Some style for that tag

    `#overlaySection {
      position: fixed;
      top: 0;
      left: 0;
      z-index: 1;
      width: 100%;
      height: 100%;
      background: rgba(255, 255, 255, 0);
      cursor: pointer;
      visibility: hidden;
      opacity: 0;
      content: "";
    }
    #overlaySection.active {
     opacity: 1;
     visibility: visible;
    }`
    
  3. Some JQuery staff

    // hide overlay on document click $('#overlaySection').click(function(){ $(this).removeClass('active'); });

and the main thing to active this overlay

$('.dropdown > span').click(function() {
    ...
    $('#overlaySection').addClass('active');
    ...
});

Hope this approach will be useful to someone. Happy coding!

nosensus
  • 1,730
  • 1
  • 11
  • 10