javascript 我可以有条件地更改在按键时输入的字符吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3923089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 02:42:16  来源:igfitidea点击:

Can I conditionally change the character entered into an input on keypress?

javascriptjquerykeypress

提问by Peter Boughton

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 notan across the board uppercasing, but onlyspecific 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 characternot the entire input.

也许我想说if ( e.which >= 97 && e.which <= 102 )if ( Wind.Direction == 'South' )或其他 - 条件本身并不重要,但大写必须仅适用于当前字符而不是整个输入。


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?

谁能提供更好的解决方案?

采纳答案by Tim Down

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

以下将完成这项工作。它基于我写给另一个问题的答案。自定义transformTypedChar功能以满足您的需求;我的例子只大写字母 ag。

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?

如果您需要在文本区域而不是文本区域上使用<input type="text">它,请注意 IE <= 8 中存在带有换行符的问题,为了简洁起见,以下代码无法处理。您可以在此处找到用于在文本区域中获取选择的跨浏览器功能:是否有 Internet Explorer 批准的 selectionStart 和 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;
    }
};

回答by Ravindra Sane

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.

当条件评估为真时,下面的代码返回假,但它使用不同的 charCode 触发相同的事件,该事件不会返回假。

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.phpand https://developer.mozilla.org/en/DOM/event.initKeyEventfor reference

你可以在 IE 中使用 fireEvent ......我使用了 http://help.dottoro.com/ljrinokx.phphttps://developer.mozilla.org/en/DOM/event.initKeyEvent作为参考

回答by VinayC

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
    }
}

回答by Thomas Clayson

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?

或者使用子字符串来获取最后一个字符并执行toUpperCase()该操作?

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

(psst ...您也可以使用 keydown 或 keypress )。

回答by jim tollan

Peter,

彼得,

You might find some inspiration here:

您可能会在这里找到一些灵感:

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

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'.

基本上是通过各种方式来查看该“区域”周围的按键事件和功能。

回答by Paul Whelan

Can you use css?

可以用css吗?

<input type="text" style="text-transform: uppercase;" />