Skip to content

当autocomplete遇到中文输入法 #23

@songhlc

Description

@songhlc

当autocomplete遇到中文输入法

1.需求场景

常见的搜索输入框,输入一个字符之后会调用后台的服务传入关键字进行查询。

以往实现,监听输入框的keydown/change事件,当输入参数改变的时候触发keydown事件,获取当前输入的参数然后调用后端服务。

1.1弊端:

  • change事件,必须要等到鼠标焦点离开输入框才会被触发
  • keydown事件则需要配合tab使用才能监听到正确的值(目前我试验是这样的),同时有时候会出现监听值和输入框中的值不匹配的情况

1.2 html5 oninput事件

关于oninput事件

该事件类似于 onchange 事件。不同之处在于 oninput 事件在元素值发生变化是立即触发, onchange 在元素失去焦点时触发。

浏览器兼容性:现代浏览器, IE9+(ie9以下需要用onpropertychange来代替)

1.3 实践

<input type="text" 
    v-model="inputtext"  
    @input="input"
    placeholder="请试试中文输入法和英文输入法">
input: function (val) {
    if (this.inputtext != this.inputvalue) {
        console.log("doquery:" + this.inputtext)
        this.inputvalue = this.inputtext
        //使用inputvalue进行查询
    }
}

查看demo地址

1.4 But Doesn't work In Vue 1.0.26

翻开vue2.1.4 的源码
//vue 2.1.4
//line 5433
el.addEventListener('compositionstart', onCompositionStart);
el.addEventListener('compositionend', onCompositionEnd);

line  5511
function onCompositionEnd (e) {
  e.target.composing = false;
  trigger(e.target, 'input');
}

原来在compositionend之后手动触发了input方法

再打开vue 1.0.26的源码
vue 1.0.26
line 4721
this.on('compositionend', function () {
  composing = false;
  // in IE11 the "compositionend" event fires AFTER
  // the "input" event, so the input handler is blocked
  // at the end... have to call it here.
  //
  // #1327: in lazy mode this is unecessary.
  if (!lazy) {
    self.listener();
  }
});

似乎好像明白了什么

input + compositionend 来联合解决这个问题

<input type="text" 
    v-model="compositiontext" 
    @input="compositioninput" 
    @compositionend="compositionend" placeholder="请试试中文输入法和英文输入法">
compositioninput: function (val) {
    if(this.compositionvalue != this.compositiontext) {
        console.log("do query:" + this.compositiontext)
        this.compositionvalue = this.compositiontext
    }
},
compositionend: function(val) {
    console.log("do query:" + this.compositiontext)
    this.compositionvalue = this.compositiontext
}

查看demo地址

1.5 回过头来看compositionevent

复合事件

复合事件(composition event)是DOM3级事件中新添加的一类事件,用于处理IME的输入序列。IME(Input Method Editor,输入法编辑器)可以让用户输入在物理键盘上找不到的字符。复合事件就是针对检测和处理这种输入而设计的。

  • compositionstart:在IME的文本复合系统打开时触发,表示要开始输入了。

  • compositionupdate:在向输入字段中插入新字符时触发。

  • compositionend:在IME的文本复合系统关闭时触发,表示返回正常键盘的输入状态。

结语: 遇到问题 + 解决问题 = 提升。其实不仅仅是vue,本身input+compositionevent都是解决不同IME输入的统一解决办法

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions