Search code examples
jqueryeventscontenteditablejquery-events

jQuery .keydown(), .keyup() ignoring "I", "B"


I've got a bit of code here, which works okay in TextMate's web preview, but Safari is doing something that I'm not sure how to get around...

$(document).ready(function(){

  $('*[contentEditable="true"]').focusin(function(){
    var _self = this;
    var isCtrl = false;
    // Bind events.
    $(window).keyup( function(e) {
      if(e.which==17 || e.which == 91) isCtrl=false;
    });
    $(window).keydown( function(e){
      if(e.which==17 || e.which == 91) isCtrl=true;
      if(isCtrl) {
        console.log(e.which);
        switch(e.which) {
          case 66:  doCommand('bold');
                    break;
          case 67:  doCommand('cut');    
                    break;
          case 73:  doCommand('italic'); 
                    break;
          case 86:  doCommand('paste');  
                    break;
          default:  break;
        }
        return false;
      }
    });
  }).focusout(function(){
    $(window).unbind();
  });
});

When control + i or command + i is pressed, we should get an event to make the text in the contentEditable area italic. The problem is, while other standard ASCII/Alpha character will fire, B and I do not. Now, if I preventDefault(), still nothing.

I need a fresh pair of eyes on this. Can anyone else see a way around this that won't prevent me from typing still?

Edit To clarify, yes this works fine with other text input elements (<textarea>, <input>, etc.). It's specifically related to contentEditable.

Also, doCommand is included here:

doCommand = function(cmd) {
  document.execCommand(cmd, null, null);
}

Solution

  • First, there's no need to detect modifier keys separately. You can find out from the keyup or keydown event whether the cmd or ctrl keys were held down using the event's ctrlKey and metaKey properties.

    Second, in contenteditable elements, keyboard shortcuts for bold and italic commands are already built in by the browser.

    It's certainly possible to intercept the keypresses you want. See http://jsfiddle.net/Hq43A/