如何让oninput()只在输入汉字而不是IME按键时触发?

问题描述 投票:0回答:2

我有一个基本的

<input type="text" oninput="funct()"></input>

但是,当我输入中文时,

oninput
也会由 IME 输入触发,而不仅仅是结果字符。例如,当我用拼音输入法输入“我们”时,我的函数
funct()
显示
console.log(WHAT_I_TYPED)
,控制台显示:

  • w
  • 子宫
  • 女人
  • 女性
  • 我们

我只想读“我们”。但是,我不想修改函数中的文本,因为中文输入法太多,无法实现。

javascript html function input ime
2个回答
2
投票

假设您的

oninput
函数如下所示(一个非常简单的示例):

function onInputHandler(value) {
    console.log(value);
}

现在,我找到了这个答案,我稍微修改了函数来处理句子/多个字母:

function letter(phrase) {
    var output = false;
    var chars = phrase.split("");
    chars.forEach(c => {if (!c.toUpperCase() != c.toLowerCase()) output = true});
    return output;
}

我们可以将其实现到我们的

oninput
处理程序中,如下所示:

function onInputHander(value) {
    if (!letter(value) {
        console.log(value);
    }
}

因此只要它是不是字母,它就会打印出该值。这是一个演示:

function letter(phrase) {
    var output = false;
    var chars = phrase.split("");
    chars.forEach(c => {if (!c.toUpperCase() != c.toLowerCase()) output = true});
    return output;
}

function onInputHandler(value) {
    if (!letter(value)) {
        console.log(value);
    }
}
<input type="text" oninput="onInputHandler(this.value)">

但是您会注意到在上面的代码片段中,它还打印出空格 - 尝试一下!我在

if
中的
onInputHandler
语句中添加了另一个条件:

if (!isLetter(value) && value.trim() != "") {
    console.log(value);
}

现在不允许任何具有不同大写/小写值的字符(大多数字母表,包括拉丁语(英语)、希腊语和西里尔语(俄语)。


但是,如果您想以另一种方式进行操作,并检查字符串中的每个字符是否都是中文字符,您可以查看这个问题及其答案。这是一个可以为中文字符构建正则表达式的示例(并不完美,但它涵盖了大部分字符):

const chineseCharacterRegex = /[\u4e00-\u9fff]|[\u3400-\u4dbf]|[\u{20000}-\u{2a6df}]|[\u{2a700}-\u{2b73f}]|[\u{2b740}-\u{2b81f}]|[\u{2b820}-\u{2ceaf}]|[\uf900-\ufaff]|[\u3300-\u33ff]|[\ufe30-\ufe4f]|[\uf900-\ufaff]|[\u{2f800}-\u{2fa1f}]/u;

这是一个检查字符串中的所有字符是否与正则表达式匹配的函数:

function chineseChar(phrase) {
    var output = true;
    var chars = phrase.split("");
    chars.forEach(c => {if (!c.match(chineseCharacterRegex)) output = false);
    return output;
}

现在我们可以在我们的函数中实现它,如下所示:

const chineseCharacterRegex = /[\u4e00-\u9fff]|[\u3400-\u4dbf]|[\u{20000}-\u{2a6df}]|[\u{2a700}-\u{2b73f}]|[\u{2b740}-\u{2b81f}]|[\u{2b820}-\u{2ceaf}]|[\uf900-\ufaff]|[\u3300-\u33ff]|[\ufe30-\ufe4f]|[\uf900-\ufaff]|[\u{2f800}-\u{2fa1f}]/u;
function onInputHandler(value) {
    if (chineseChar(value)) {
        console.log(value);
    }
}

注意:我确实知道正则表达式并不匹配所有中文字符,但这个答案告诉您原因,并且您可以通过阅读答案并按照此线程中的链接找到大多数其他字符unicode。

希望这有帮助!


0
投票

我建议使用

event.isComposing
属性来识别是否在 IME 组合过程中插入输入数据,而不是尝试仅触发非 IME 字符的输入。

inputElement.addEventListener("input", (event) => {
    if (!event.isComposing) {
        // Do what you need to do with non-IME input
    }
});

有关生命周期的更多详细信息(以及何时

isComposing
属性为
true
以及何时
false
),请查看 组合期间的关键事件 规范。

© www.soinside.com 2019 - 2024. All rights reserved.