Override OSX press and hold the accent button in the browser

If you press and hold a key in OSX, you will get a pop-up window in which you can select different characters. I wrote a small webtool: http://kasperpeulen.imtqy.com/PressAndHold/ , which does the same, but I added a lot of math symbols to the popups. Now I want to override my own OSX tool. I tried:

$('input').on('keydown', function (e) {
    e.preventDefault();
});

DEMO: http://jsfiddle.net/nggnjo5a/2/

In Firefox, this overrides the native OSX tool. Unfortunately, this does not happen in chrome and safari. Is there any other way to make sure the native OSX application is disabled on my website?

+4
source share
1 answer

I was fortunate enough to turn the field type="text"into a field type="password"and return very quickly. I noticed that holding the key in the password field does not cause an accent popup and wants to take advantage of this behavior. This trick doesn't work 100% of the time, and it's an ugly hack - but it's better than nothing. Below is the complete code that I am using. I fire this on the first input field focus event.

this.disableAccentPopup = function(_input, callback){       
    var last_key_down   = false; // last key pressed
    var last_key_count  = 0; // number of keydown events for last key pressed
    var keys_down       = {}; // all keys being held down

    var input = _input.cloneNode(true); // We will swap this with the original input on first focus
    input.type = "password"; // Password fields don't suffer from accent UI
    input.value = ''; // Empty this so we don't see the password bullets
    input.focus();

    // Right before focus...
    _input.addEventListener("focus", function(e){
        // This setTimeout is needed so we can get the proper selectionStart and selectionEnd values
        setTimeout(function(){
            var t = _input.value;
            var s = _input.selectionStart;
            var e = _input.selectionEnd;
            _input.parentNode.replaceChild(input, _input);
            input.focus();
            // This setTimeout is needed to set the input type w/o breaking the input behavior
            setTimeout(function(){
                input.value = t;

                input.type = 'input';

                input.setSelectionRange(s, e);
                if (callback) {
                    setTimeout(function(){
                        callback(input);
                    }, 0);
                }
            }, 0);
        }, 0);
    });

    input.addEventListener("keydown", function(e){
        keys_down[util.keyIdentifierToKeyCode(e)] = true;
        if (!e.metaKey && e.keyIdentifier.substr(0,2) == "U+") {
            if (last_key_down && last_key_count >= 1) {
                // if this is not the first keydown event for this char,
                // we can safely set the type to input

                input.type = 'input';

                if (last_key_down == util.keyIdentifierToKeyCode(e)) {
                    e.preventDefault();
                } else {
                    last_key_count = 0;
                }
            }
            last_key_down = util.keyIdentifierToKeyCode(e);
            last_key_count++;
        }
    });

    input.addEventListener("keyup", function(e){
        delete keys_down[util.keyIdentifierToKeyCode(e)];
        if (!e.metaKey) {
            // if _all_ keys are up
            if (Object.keys(keys_down).length == 0) {
                last_key_down = false;
                last_key_count = 0;
            }
        }
    });
}
0
source

All Articles