Javascript fires two events - onkeypress and onclick
Asked Answered
S

8

6

Problem is when I press a key over a radio button, element MyFunc fires twice - once for onkeypress event, another time for "click" event.

Question "Why?" I need to handle this by two different ways, but now I can not recognize what initial event was. When I click a mouse it fires just for "click" event.

<ul>
    <li>
        <input type="radio" onkeypress="MyFunc(event, this)" onclick="MyFunc(event, this)" name="myList" id="MyId_1" />Topic 1
        <input type="radio" onkeypress="MyFunc(event, this)" onclick="MyFunc(event, this)" name="myList" id="MyId_2" />Topic 2
    </li>
</ul>

function MyFunc(e, obj) {
    alert(e.type); // alerts "keypress" and then "click"
    // Do my stuff
}
Steere answered 2/3, 2010 at 13:27 Comment(0)
E
3

If 2 events are being fired during pressing a key then check event.detail property in onClick function. if event.detail = 0 then it means that mouse was not clicked on that element and we can ignore it. event.detail

Entrammel answered 13/2, 2016 at 15:18 Comment(0)
R
1

The onclick Event is fired, when the radio button gets selected. Since you select it by pressing a key, both events will get fired. First the onkeypress event and then the onclick event.

Renowned answered 2/3, 2010 at 13:40 Comment(3)
But how do you prevent this from occuring?Bismuthous
You can't prevent this behaviour as far as I know.Renowned
It is very strange. What is the point to handle these events together? :-/Steere
I
1

It can be done and without resorting to frameworks which are always bulky and slow. The trick is to record which event happened at what point in time and then on top of that to work within a time frame. When you trigger the keypress event the click event is triggered immediately afterwards, here is a list of how quickly the click event is triggered after the keypress event...

Chrome 39.0: 0ms

Firefox 31.0 ESR: 18~20ms

IE 11: 2~4ms

Opera 12.1: 0ms

Chrome and (real) Opera don't wait, IE is reasonably quick and Firefox takes it's time so-to-speak; the range to work with (at least on my system) is 0~20 ms. Programmatically I'll set the limit to 50ms for people still using junky computers that are too busy with the 150 useless processes in the background.

Note you'll have to utilize the window global level events though this seems to work reliably for me in all the browsers that I mentioned.

var option = new function() {this.name = '';}


window.onclick = function(event)
{
 option.clickDate = new Date().getTime();
}


window.onkeypress = function(event)
{
 option.keyCode = event.keyCode;
 option.keyCodeDate = new Date().getTime();
}


function MyFunc(e,obj)
{
 if (option.keyCodeDate && option.clickDate && 
 (
  (option.clickDate - option.keyCodeDate)>=0 && 
  (option.clickDate - option.keyCodeDate)<51)
 {alert('keypress event');}
 else {alert('click event');}
}
Isogloss answered 19/1, 2015 at 15:47 Comment(0)
D
0

you could add a 3rd parameter to your function

function MyFunc(e, obj, click) {
    if (click) { } // do stuff
    else { } // do other stuff
}

Now add in a bool to your events...

<input type="radio" onkeypress="MyFunc(event, this, false)" onclick="MyFunc(event, this, true)" name="myList" id="MyId_1" />Topic 1
<input type="radio" onkeypress="MyFunc(event, this, false)" onclick="MyFunc(event, this, true)" name="myList" id="MyId_2" />Topic 2
Demark answered 2/3, 2010 at 13:38 Comment(1)
The problem is that they fire simultaneously. I can recognize what was clicked using e.type property. It returns "keypress" or "click".Steere
D
0

I would create two separate handlers: one for the click event and one for they keypress.

Then your handlers can extract whatever you need from the event and call a third function that has the common logic.

Your onkeypress would have to ignore the event for the space and enter keys. I don't understand why you are listening to the keypress event though. Could you elaborate? If you explain what you'll do, maybe we can be more helpful.

Dibbell answered 10/3, 2010 at 17:46 Comment(0)
V
0

A key event is for keyboard only users to activate a button, but if you're using a button "click" should be the only event needed as it gets fired when pressing SPACE BAR. If you have events on a custom control, "key" event and "click" can both be used and will not fire together.

Vola answered 4/2, 2017 at 19:39 Comment(0)
N
0

I've looked at the properties .type and .detail as suggested. type stays as click on both firefox and chromium. detail stays as 0 on chromium, but changes to 1 when actually clicking with the mouse on firefox. But .x and .y do change on both firefox and chromium when clicking with mouse, while remaining as 0 when the event originates from keyboard actions.

Novah answered 2/3, 2023 at 9:5 Comment(0)
B
-1

Use onMouseDown instead of onclick within JavaScript and for consistency add you onKeyPress event here too - taking the event out of the HTML tag.

Sudo Code:

var myRadioButton = document.getElementById('radio');

myRadioButton.addListener("radioClick",onMouseDown);
myRadioButton.addListener("radioKey",onKeyPress);

radioClick()
{
 //code to do stuff
}

Check out jQuery: http://jquery.com/ for the actual code and easy way to write your JavaScript.

Bismuthous answered 2/3, 2010 at 13:47 Comment(3)
I will try it. I think I tryed onMouseDown, but I worked like OnClick. Maybe addListener helps. Will come back soon with results.Steere
I've tried this solution using jQuery. It did not help. "OnMouseDown" did not fired anything. It just did not call my function. If I user "OnClick" with addListener it gives the same problem. I do not have any solution right now. Any ideas?Steere
Great that you mentioned consistency but then you bombed it by suggesting a framework. If I had searched for this issue via Google this page wouldn't have come up because I -jquery to find answers, not dumping bandwidth on users. Please stick to real JavaScript.Isogloss

© 2022 - 2024 — McMap. All rights reserved.