梁越

关于onChange事件和omComposition事件的先后顺序解决,采用onKeyDown

0 人看过

巧妙解决在张文输入法下打拼音的过程会不断触发onChange事件的问题

也许你和我一样,在编写vue项目或者react项目的时候,对某个输入框或者编辑器监听输入事件,你有一些逻辑逻辑处理需要放在onChange函数里,这里不同项目函数名也不一样,我用monaco-editor的内容监听是onDidChangeContent

this.monacoEditor.getModel().onDidChangeContent((event) => {
    //dosomething
}

结果你会发现中文输入法打拼音时,居然也会触发onDidChangeContent事件,这个可能和中文输入的处理有关,还好monaco-editor也想到了,提供了onCompositionStartonCompositionEnd事件来监听是否在中文输入打拼音状态,所以你可以用一个状态变量来控制

this.compositonState = "end";

    this.monacoEditor.getModel().onDidChangeContent((event) => {
    //dosomething
});

//中文输入法开始
this.monacoEditor.onDidCompositionStart((event) => {
    // console.log("comstart");
    this.compositonState = "sta";
});
//中文输入法结束
this.monacoEditor.onDidCompositionEnd((event) => {
    // console.log("comend");
    this.compositonState = "end";
});

看起来逻辑没问题,但是运行又出现问题了,因为有些浏览器(chrome)的执行顺序居然是onDidChangeContent -> onDidCompositionEnd,所以状态改变了却没有触发onchange事件,然后有些解决方案是在onDidCompositionEnd里再写一遍onDidChangeContent的逻辑,这种方案在某些简单场景下可以,但是如果只能在onDidChangeContent里执行,那可能要用上onKeyDown函数,或者任意在onDidChangeContent的键盘函数,我这里采用onKeyDown

其实就是在打拼音的时候等待空格,空格落下然后改变状态,一般来说空格是确定按钮

this.compositonState = "end";
this.monacoEditor.getModel().onDidChangeContent((event) => {
    //dosomething
});

//中文输入法开始
this.monacoEditor.onDidCompositionStart((event) => {
    // console.log("comstart");
    this.compositonState = "sta";
});
//中文输入法结束
this.monacoEditor.onDidCompositionEnd((event) => {
    // console.log("comend");
    this.compositonState = "end";
});
//中文输入法下等待空格
this.monacoEditor.onKeyDown((event) => {
    // console.log(event);
    if (this.compositonState == "sta" && event.code == "Space") {
        console.log("触发");
        this.compositonState = "end";
}
});

但是上面这个方案还需要考虑很多边界问题,比如输入法可能按到数字键或者某些符号键也会结束,所以以上方法自己参考吧