Can I conditionally change the character entered i

2019-01-08 23:13发布

Is it possible to change the character which has been entered on keypress, without doing it manually?

For example, if I want to force uppercase letters based on some condition, it'd be nice to do the following:

function onKeypressHandler(e)
{
    if ( condition )
    {
        e.which -= 32;
    }
}

But of course that doesn't work.

NOTE: This is not an across the board uppercasing, but only specific characters.

Maybe I want to say if ( e.which >= 97 && e.which <= 102 ) or if ( Wind.Direction == 'South' ) or whatever - the condition itself is not important, but the uppercasing must only apply to the current character not the entire input.


I can do it by manually appending the changed character, but this is an ugly and messy way of doing it, and probably slower than it could be.

function onKeypressHandler(e)
{
    if ( condition )
    {
        $j(this).val( $j(this).val() + String.fromCharCode( e.which - 32 ) );
        return false;
    }
}

A specific flaw with this method - if selecting all input text and entering a key, if it drops into this then it doesn't remove existing content, but simply appends to the content the user wanted removed. (Would need to investigating detecting any selected text to solve that, which makes this one even uglier.)

Can anyone provide a better solution?

6条回答
欢心
2楼-- · 2019-01-08 23:41

Peter,

You might find some inspiration here:

http://www.maconstateit.net/tutorials/JSDHTML/JSDHTML15/jsdhtml15-05.htm

basically walks around the various ways to look at the keypress events and functions around that 'area'.

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-01-08 23:42

Not really sure what you want but will this work?

$('#my_element').keyup(function(){ $(this).val().toUpperCase(); });

or use a sub string to get the last character pressed and do toUpperCase() on that?

(psst... you can use keydown or keypress too).

查看更多
Lonely孤独者°
4楼-- · 2019-01-08 23:46

You've got to see this.. I was pretty happy with myself after getting it to work..

You obviously would want to include sufficient criteria to avoid going into a loop here.

The code below returns false when condition evaluates to true, but it fires the same event with a different charCode which will not return false.

document.getElementById("input1").onkeypress = Handler;
function Handler(e)
{
    e = e || window.event;
    if ( e.charCode == 97 )
    {
        var evt = document.createEvent("KeyboardEvent");
        evt.initKeyEvent("keypress",true, true, window, false, false,false, false, 0, e.charCode -32);
        this.dispatchEvent(evt);
        return false;
    }
    return true;
}

you could use fireEvent in IE... I used http://help.dottoro.com/ljrinokx.php and https://developer.mozilla.org/en/DOM/event.initKeyEvent for reference

查看更多
Explosion°爆炸
5楼-- · 2019-01-08 23:47

How about preventing default action and then triggering the keypress? Something like,

function onKeypressHandler(e)
{
    if ( condition )
    {
        e.preventDefault();
        // create new event object (you may clone current e)
        var ne = new jQuery.Event("keypress");
        ne.which = e.which - 32;
        $(e.target).trigger(ne);   // you may have to invoke with setTimeout
    }
}
查看更多
劳资没心,怎么记你
6楼-- · 2019-01-09 00:01

The following will do the job. It's based on an answer I wrote to another question. Customize the transformTypedChar function to suit your needs; my example capitalizes only the letters a-g.

If you need this on a textarea rather than an <input type="text"> then be aware that there are issues in IE <= 8 with line breaks that the following code doesn't handle for the sake of brevity. You can find the cross browser function for obtaining the selection within a textarea here: Is there an Internet Explorer approved substitute for selectionStart and selectionEnd?

function transformTypedChar(charStr) {
    return /[a-g]/.test(charStr) ? charStr.toUpperCase() : charStr;
}

document.getElementById("your_input_id").onkeypress = function(evt) {
    var val = this.value;
    evt = evt || window.event;

    // Ensure we only handle printable keys, excluding enter and space
    var charCode = typeof evt.which == "number" ? evt.which : evt.keyCode;
    if (charCode && charCode > 32) {
        var keyChar = String.fromCharCode(charCode);

        // Transform typed character
        var mappedChar = transformTypedChar(keyChar);

        var start, end;
        if (typeof this.selectionStart == "number" && typeof this.selectionEnd == "number") {
            // Non-IE browsers and IE 9
            start = this.selectionStart;
            end = this.selectionEnd;
            this.value = val.slice(0, start) + mappedChar + val.slice(end);

            // Move the caret
            this.selectionStart = this.selectionEnd = start + 1;
        } else if (document.selection && document.selection.createRange) {
            // For IE up to version 8
            var selectionRange = document.selection.createRange();
            var textInputRange = this.createTextRange();
            var precedingRange = this.createTextRange();
            var bookmark = selectionRange.getBookmark();
            textInputRange.moveToBookmark(bookmark);
            precedingRange.setEndPoint("EndToStart", textInputRange);
            start = precedingRange.text.length;
            end = start + selectionRange.text.length;

            this.value = val.slice(0, start) + mappedChar + val.slice(end);
            start++;

            // Move the caret
            textInputRange = this.createTextRange();
            textInputRange.collapse(true);
            textInputRange.move("character", start - (this.value.slice(0, start).split("\r\n").length - 1));
            textInputRange.select();
        }

        return false;
    }
};
查看更多
We Are One
7楼-- · 2019-01-09 00:03

Can you use css?

<input type="text" style="text-transform: uppercase;" />
查看更多
登录 后发表回答