Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

当autocomplete遇到中文输入法 #23

Open
songhlc opened this issue Jan 2, 2017 · 0 comments
Open

当autocomplete遇到中文输入法 #23

songhlc opened this issue Jan 2, 2017 · 0 comments
Labels

Comments

@songhlc
Copy link
Owner

songhlc commented Jan 2, 2017

当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输入的统一解决办法

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant