动态获取input内容文本(排除候选拼音文本) - js事件

要想通过事件实时获取文本框文本,一开始是想到下面的方法,但实际效果都存在一定的缺点。

 


 

通过change/blur事件获取

  1. change事件只有在选中点击或者失焦的时候,才能够触发。
  2. blur事件则是只能在失焦才能除法。

 

 

我最初选择的是change事件,而这样显然是不符合实时获取的要求的。

 

然后在查找文档的时候,发现了input事件,这里的input指的是事件的名字。mdn对于input事件的解释是:

每当<input>元素的value值改变时,都会触发这个事件。

 

这个显然很适合我们的需求,先写个例子看一下效果。

<span>name:</span>
<span id="txt"></span><br/>
<label for="lastName"></label>
<input id="lastName" type="text"><br/>
let txt = document.getElementById('txt');
let lastName = document.getElementById('lastName');
let num = 0;
lastName.addEventListener('input', ()=>{
    txt.innerText = lastName.value;
    console.log(num++);
});

 

试了一下,效果的确很好,实时显示。

 

 

 

对于一般的普通文本框实时获取,input事件的确合适。但特殊情况下依然存在一些问题:

输入法的待选文本(拼音)也会同时获取显示,并且每一次输入都会触发事件。这会让显示的结果不够美观,同时,如果是需要实时获取并进行其它操作的话,比如模糊查询等,这会在输入时就产生很多次请求。(当然也可以使用防抖解决)

 

所以继续查找是否有更优的解决方案,于是发现了以下几种事件:

  1. compositionstart 事件触发于一段文字的输入之前
  2. compositionend 事件触发于当文本段落的组成完成或取消时
  3. compositionupdate 事件触发于字符被输入到一段文字的时候,在 compositionstart 事件之后不会立即执行

这些是MDN上找到的解释,很明显可以看出,这几个事件特别是前两个,是针对于有输入法候选词情况下产生的,很适合我们这种场景。有趣的是在MDN中,这几个事件被列在 Element 节点下,而不是事件节点下。

 

 

 

首先要实时获取文本框数据,在输入法状态输入完成后获取,使用 compositionend 事件。 但是在不使用输入法,或者删除输入的字符,是无法触发事件的,那么可以结合一下 input 事件使用。大致思路就是这样。示例:

let type = true;
lastName.addEventListener('compositionstart', ()=> type = false);
lastName.addEventListener('compositionend', ()=> type = true);
lastName.addEventListener('input', ()=>{
    window.setTimeout(()=>{
        if(type) txt.innerText = lastName.value;
    }, 0);
});

加定时器是为了保证 compositionend 事件执行后 type 状态改变成功,否则 input 事件触发时,type 可能仍为false。

 

测试效果:

 

 

 效果差不多已经达到了。

 

兼容性:

input 事件只适合 ie9 以上版本,且只支持文本和密码输入框。

composition~ 事件 MDN 上是支持 ie 的,但并未写清版本。

案例代码 es5 语法时最低支持 ie9。

 

参考:

posted @ 2020-03-06 16:51  镜暮  阅读(783)  评论(0编辑  收藏  举报