0

I am attempting to overwrite a core jQuery event, in this case the keydown event. My intention is to preventDefault() functionality of Left(37), Up(38), Right(39) and Down(40) to maintain the consistency of hot keys in my web application.

I am using the solution provided here for the conditional charCode preventDefault problem.

For some reason, my function overwrite is simply not firing, and I cannot put my finger on the problem. I am afraid that over the past 30 minutes this issue has resulted in some hair loss. Anybody have the remedy?

/* 
Modify Keydown Event to prevent default PageDown and PageUp functionality
*/
(function(){
    var charCodes = new Array(37,38,39,40);
    var original = jQuery.fn.keydown;

    jQuery.fn.keydown = function(e){
        var key=e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
        alert('now why is my keydown mod not firing?');
        if($.inArray(key,charCodes))
        {
          alert('is one of them, do not scroll page');
          e.preventDefault();
          return false;
        }
        original.apply( this, arguments );
    }
})();
Community
  • 1
  • 1
Sandwich
  • 2,132
  • 1
  • 21
  • 27

1 Answers1

1

A problem with your solution is that keydown does not accept an event as it argument, so you mental model of what is going on is incorrect. How the event gets created is probably complicated, so why not just write a plugin which uses keydown and builds upon it, slotting your logic in before a given callback:

(function($){
    var charCodes = new Array(37,38,39,40);

    $.fn.limitedkeydown = function(callback) {
        this.keydown(function(e) {
            if ($.inArray(e.keyCode, charCodes))
                e.preventDefault();
            callback(e);
        });
    };
})(jQuery);

That way the original (untouched) version is still available to you, so can equally use both methods:

$('selector').keydown(function(e) {});
$('selector').limitedkeydown(function(e) {});
Marcus Whybrow
  • 18,372
  • 7
  • 64
  • 88
  • Your solution is adequate, however, upon looking into the keydown function, I see that keydown does indeed have an event parameter. So this does not explain why the function is not firing. Is it because the object string for keydown is not jquery.fn.keydown, but actually jQuery.event.special.change.keydown? Do a find for 'keydown' - http://code.jquery.com/jquery-1.4.3.js – Sandwich Jan 04 '11 at 21:00
  • Sorry, I meant: jQuery.event.special.change.filters.keydown – Sandwich Jan 04 '11 at 21:06
  • I had a look at the source, however looking at the [API docs](http://api.jquery.com/keydown/) for `keydown` you can see the arguments the function expects. There may be a difference in how jQuery implements its event structure, for example try searching for keyup and it only appear once (in the `each` list of possibilities). – Marcus Whybrow Jan 04 '11 at 21:09
  • Your solution has pointed me in the right direction, but your raw example simply does not work. I believe this has something to do with an incorrect parameter count. For instance, the arguments for keydown is: .keydown('key',fn) – Sandwich Jan 04 '11 at 21:28
  • The arguments to `keydown` are either none, a single function to call, or event data to use and a function to call (not what you suggested there). Also in what way does it not work, does the event not fire at all, or does the prevention not take effect. What is the exact problem? – Marcus Whybrow Jan 04 '11 at 21:43
  • The event was not firing to fault of my own. However, I have solved the issue through alternative measures. You have provided a good deal of information, and anyone with the same problem will be helped by your solution. I will leave it unchecked for a few days just in case someone answers the question of how to correctly overwrite keydown, otherwise it's yours. Thanks again Marcus, I appreciate your help :D – Sandwich Jan 04 '11 at 21:58