28

I am experiencing problem with Firefox 32 when I bind action on click event of span element inside a button element. Other browsers seems to works well.

Here the code illustrating the issue on jsFiddle.

<span onClick="alert('test');">**Working**</span><br>
<button>inside a button <span onClick="alert('test');">**Not working**</span></button>

Does anybody know why and if it's a bug or a feature ?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Jrmi
  • 283
  • 1
  • 3
  • 5
  • 1
    Its funny because it works fine on Chrome. But I'm told it also doesn't work on IE so mostly it doesn't work. – chowey Nov 28 '16 at 21:33

5 Answers5

46

You have to add the pointer-events property to the span element.

button span {
  pointer-events: none;
}
informatik01
  • 16,038
  • 10
  • 74
  • 104
marco-s
  • 613
  • 5
  • 6
  • Works for me on FF 66. For some discussion see https://css-tricks.com/slightly-careful-sub-elements-clickable-things/ – Brian Burns Apr 05 '19 at 16:07
  • 1
    This should've been the accepted answer. It works even on chrome.(in 2022) – Sam Apr 04 '22 at 14:37
31

As far as i known clicking the children elements won't work because it is nested inside a button. A button is not container for child elements - only for text.

If you try like below it always tell that you clicked the button.

<button type="button" onclick="alert('You clicked the button!');">
   inside a button <span onClick="alert('clicked span');">**Not working**</span>
</button>

So, my suggestion is to use another span or a div

<div class="button_replace">
  inside a div <span onClick="alert('clicked span');">**working**</span>
</div>

Hope it helps...

Note: Your code will work in chrome but not in firefox and my answer is alternative solution for making work in firefox

wscourge
  • 10,657
  • 14
  • 59
  • 80
SDK
  • 1,532
  • 1
  • 15
  • 31
6

Add a pointer-event to your button in css like:

button span {
    pointer-events: none;
}

Clicks on the button element will be ignored

Jamel Toms
  • 4,525
  • 2
  • 27
  • 26
Jasper Seinhorst
  • 1,056
  • 6
  • 19
3

Working
inside a button Not working

What you actually want to do here is have a click event on the button - always the button, as that is the native HTML element and has built in accessibility for all.

The reason your button click won't fire if you click on something wrapped in a span (or or etc) inside a button is because you are listening for a click on event.target (what's actually clicked) and not on event.currentTarget.

If you want to listen to the button click itself (a click anywhere inside the button, including the span) you would use something like this:

HTML:

<button type="button" class="jsAlertOnClick">
  Inside a button 
  <span onClick="alert('Span Clicked, and...');">I'm in a span</span>
</button>

Javascript:

const myButton = document.querySelector('.jsAlertOnClick');

function handleBtnClick(event) {
  const btn = event.currentTarget;
  window.alert(btn + 'has been clicked!');
}

myButton.addEventListener('click', handleBtnClick);

If you click on the span, that alert will fire first, followed by the button one. If you click elsewhere in the button, only that alert will fire.

Grace Snow
  • 31
  • 1
1

Depending on the reason you have a span inside the button, you might be able to get rid of it entirely. I was just dealing with a similar issue where we had a span inside the button, but the span was being used to hold a glpyicon:

    <button class="btn btn-default pull-right" type="button">
              <span class="glyphicon glyphicon-refresh"></span>
    </button>

I finally discovered there's an easier and cleaner way - at least in this case. Just put the glyphicon class stuff inside the button class:

    <button class="btn btn-default pull-right glyphicon glyphicon-refresh" type="button">
    </button>
harpchil
  • 11
  • 2
  • Problem is that span catchs event and doesn't push it to the parent. You need pass event after span handle it. – Dawid Wekwejt Oct 10 '22 at 19:14
  • 1
    @DawidWekwejt - You're right, of course. My point was that *if* the only reason you have a span inside the button is to hold a glyphicon, you can just remove the span entirely and put the glyphicon in the button itself. That way you don't have to worry about setting up an event handler on the span and all that stuff. – harpchil Oct 11 '22 at 20:28
  • Right, your approach is much easier and really clear. – Dawid Wekwejt Oct 12 '22 at 07:34