Search code examples
javascripthtmlgoogle-chromefirefoxsafari

Detecting composed characters to ignore some of them


I am writing a contenteditable-based widget which needs to handle text input on its own. It is fairly easy to deal with both ascii and non-ascii characters with something like this:

container_element.addEventListener('keypress', function(event) {
    if (event.ctrlKey || event.altKey || event.metaKey) {
        return;
    }
    if (event.which != 0 && event.charCode != 0) {
        event.preventDefault();
        var c = String.fromCharCode(event.which);
        handle_character(c);
    }
});

Now, if I configure my local system to input non-ascii characters through dead key composition (say, altgr for example), the above fails miserably. Fancy editors like google docs appear to handle this case quite well across a wide range of OSes and browsers without any need for external plugins so, it is clear that it is possible from the browser-fired events to detect which character is generated from a composition sequence of dead keys.

However, I have been unable to find out how exactly (not even for a single browser/OS combination, say, Chrome/Linux).

Hence my question: would anyone know how to detect which character is being input from a keypress or keydown handler when we are getting a dead-key composition sequence ?


Solution

  • It looks I'm not the only one looking for it :) I just found a bunch of events related to composition state that may suits your need. I use it to block keyboard events when i'm in a middle of a composed char. The key is to add a simple :

    var block = false;
    input.addEventListener('compositionstart', function() { block = true; });
    input.addEventListener('compositionend', function() { block = false; });
    

    and use it later in your code within the input event :

    input.addEventListener('input', function() {
        if (block) { return; }
        console.log(input.value);
    });
    

    Demo: http://jsfiddle.net/kde4gvxn/1/