2

HTML

<button id="clickMe" tabindex=0>Click Me!</button>

JS

$('#clickMe').button();
$('#clickMe').click(function() {
    alert('hey');
});

$(document).keypress(function (e) {
    var key = e.keyCode ? e.keyCode : e.which;
    //detect when the user has hit enter
    if (key == 13) {
        //click the focused element
        $(document.activeElement).click();
    }
});

Why does this alert fire twice when you hit tab to focus the button and enter for the keypress event, but only fires once when you click the button with the mouse?

Demonstration

EDIT: tab + enter doesn't work at all in IE 10

4 Answers 4

8

Because hitting "Enter" when focus is on a button triggers the "click" event natively. You also get a "keypress" event, and from that you trigger the "click" event again.

Sign up to request clarification or add additional context in comments.

6 Comments

I wonder if we should tell them about e.preventDefault() and e.stopPropagation() ;-)
@JohnMacIntyre first thing would be to figure out whether the keypress happens before or after the click. I think it happens before, in which case then yes the .preventDefault() would be the trick (in the "keypress" handler).
A small addendum: this is true for IE (Tested in IE11, with IE9 compatibility mode turned on), but not in Firefox or Chrome, where no click event on enter was fired, making manual binding of the key necessary.
More info: apparently, in plain IE11 (without compatibility mode) the click event is not bound the same way as in the previous versions, so I'm manually assigning a handler, and the handler is only firing once.
@IliaKoulikov here is a simple jsbin. When I focus on the button in Firefox, pressing "Enter" causes both a "click" and a "keypress".
|
4

I know it's an old post but while I was looking for a solution of a nearly identical problem I've found out that the default type of a <button> element is "submit". This means that if you press Enter anywhere in the <form> containing this button, it will automatically submit.

Actually, if you press enter in any of those two input, the snippet closes. If you define a function to click a button on the Enter keypress event it will trigger twice unless you add a "button"to the button element, because you trigger it both with your function and the automatic submit.

TLDR: add type="button" to your button element.

$(document).ready(function(){
  
  $(document).on('click','#submit_type',function(){
    console.log($(this).attr('id'))
  });

  $(document).on('click','#button_type',function(){
    console.log($(this).attr('id'))
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form1">
  <input>
  <button id ="submit_type">Can enter</button>
</form>

<form id="form2">
  <input>
  <button type="button" id="button_type">Cannot enter</button>
</form>

Comments

0

I'm responding here to Pointy's comment instead of in the comments due to lack of space;

I can confirm that I can see the click getting triggered in the JSbin, but I am not sure how to account for the difference between my actual application code's behavior and that on the page. Perhaps it was because I bound my "click" on a separate line instead of chaining it.

I have not yet learned how to use JSBin, but I make a solemn promise to do this soon. However, my info came from experimentation in my own code:

$(settings.selectors.patientSearchSubmitButton).click(validatePatientSearch);

Was followed by

$(settings.selectors.patientSearchSubmitButton).click(alertOnClick);

I also had another binding:

        $(settings.selectors.patientSearchParameter).keypress(function (e) {

            if (e.which == 13) {//Enter key pressed
                validatePatientSearch();
            }
        });

patientSearchParameter was a field next to the button. When I focused on the field and hit "enter" in chrome, ff, plain IE11, the validatePatientSearch function ran once, and the alertOnClick function did not run. When I did the same thing in IE11 compatibility mode for IE8, 9, 10; the function ran twice, and the alertOnClick was triggered. I am not certain how I could prove it, but this has been my experience, and this was repeated behavior over 20 or so test tries. I am using Windows 7 64 bit. Not sure what else could be causing it to behave this way, but I hope it can be useful to someone.

Could it be because my click was bound to the button and not the field?

Comments

0

I ran into this problem just today and the suggestions were vague and the one suggestion to use type="button" did not help at all.

My solution was simple and worked well on Chrome, Firefox and even Safari.

My solution as follows:

$('#my_trigger').on('keypress click', function(e) {
  e.preventDefault();
  e.stopPropagation();
  // do something
})

Both events, keypress and click are necessary as well as e.preventDefault() & e.stopPropagation()`

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.