Javascript onChange arrow keys

Viewed 8083

Ok, so we all know that onChange is used to execute javascript code on a select statement when the option changes. However, if you change a select statement using the arrow keys, the onChange event is not called. Is there a way around this? Please help! I'm OCD I know.

--EDIT 1--

Just tested this in IE and arrow keys do work. Apparently it's just Chrome. ** Goes to check firefox

-- Edit 2 --

Tested in Firefox and realized just before an answer below talked about the onBlur action being required for the change. So the answer here is:

Internet Explorer recognizes onChange events from the keyboard as well as clicking on them. Firefox and Chrome both require key events to be followed by blur event in order to call onChange.

Now normally, I don't like Internet Explorer, because it's a piece of garbage... But I think I... unfortunately, have to say they got that one right.

My understanding as to the reasoning for the blur event on chrome and firefox is to save resources, but I disagree with that. I feel it should follow the literal interpretation of the command onChange... Sigh... I suppose I'm probably wrong somehow, though.

6 Answers

This is a pretty dirty hack, but you can force the the change event to fire by doing this:

element.addEventListener('keyup', function(evt){
    evt.target.blur();
    evt.target.focus();
}, false);

So you'd register an event listener for change as well, and that function would get called when the user presses a key on the <select> via the code above.

You may want to scope this only to Firefox, but AFAIK you'd have to use UA sniffing for that so it's up to you if that's acceptable.

Source

Here's a realization of this request. For brevity only showing the code. See https://github.com/ida/skriptz/blob/master/js/fields/select/selection_changed.js for long explanations in comments.

function addSelectionChangedListener(selectionEle, onChangeDoWithEle) {

  var selectedIndex = null

  function onChangeEvent(eve) {
    // If selection-change was caused of an option's click-event:
    if(eve.explicitOriginalTarget.tagName.toLowerCase() == 'option') {
      // We want to trigger passed event-handler:
      onChangeDoWithEle(eve.target)
    }
  }

  function onKeyEvent(eve) {

    // Key-event is keydown, remember current selectedIndex:
    if(eve.type == 'keydown') {
      selectedIndex = eve.target.selectedIndex
    }
    // Key-event is keyup, if selection changed, trigger passed handler:
    else if(selectedIndex != eve.target.selectedIndex) {
      onChangeDoWithEle(eve.target)
    }

  }

  selectionEle.onchange  = function(eve) onChangeEvent(eve)
  selectionEle.onkeydown = function(eve) onKeyEvent(eve)
  selectionEle.onkeyup   = function(eve) onKeyEvent(eve)

}
Related