DOM Composition 事件

做实时的表单表单校验时,如果输入的是非拉丁语言,那你可能会遇到下面的问题:

 

 

如上图所示,文本框不允许输入 ' 之类的特殊字符,当用户在敲击拼音、还未最终输入时就已经触发了校验,提示输入不合法,有点尴尬。通常我们都是监听 input 或者 change 事件来校验用户输入,也就是说在用户输入拼音的过程中就已经触发了相关事件,进而触发校验。

现实中遇到类似问题时,我们一般会认为是输入法处理不当,这种底层的问题不应该由前端来填坑,然后就放弃治疗了。

那到底有没有前端规避这一问题的方法呢?还真有:DOM 提供了 Composition 事件 API。不过,应该很少有人关注到这几个事件,或者是笔者太孤陋寡闻,不然不会最近才留意到。

根据规范,Composition 事件触发顺序如下:

  • 输入开始时触发 compositionstart
  • 选择字/词完成输入时触发 compositionend
  • 输入过程中每次击键时触发 compositionupdate,包括 start 事件以后立即触发,end 事件以前立即触发
  • Composition 事件以后触发 input 事件

通过 Composition 事件,在 compositionend 里校验非直接输入,就能有效地避免不恰当的校验时机产生的用户体验问题。

<h2>切换至中文或者其他非拉丁语系输入法</h2>

<p>
     <label for="title1">监听 Input 校验</label>
     <input type="text" id="title1">
</p>

<p>
     <label for="title2">中文输入法时监听 Composition 事件校验</label>
    <input type="text" id="title2">
</p>
.error {
 border: 3px solid red;
}
const title1 = document.getElementById('title1');
const rule = /^[1-9a-zA-Z\u4e00-\u9fa5]+$/;
const errorClassname = 'error';

function validate(node) {
 const value = node.value;

 if (!rule.test(value)) {
  node.classList.add(errorClassname);
 } else {
  node.classList.remove(errorClassname);
 }

 console.log(`Input -> ${value}`);
}

title1.addEventListener('input', function(event) {
 validate(this);
});

let compositio = false;

title2.addEventListener('compositionstart', function() {
 compositio = true;
});

// 非拉丁语言输入校验
title2.addEventListener('compositionend', function(event) {
 validate(this);
});

// 普通输入校验
title2.addEventListener('input', function(event) {
 if (!compositio) {
  validate(this);
 }
})

 

原文链接:https://csspod.com/dom-composition-event/

参考链接:

https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionstart_event

https://blog.evanyou.me/2014/01/03/composition-event/

posted @ 2019-09-25 10:47  沐子馨  阅读(673)  评论(0编辑  收藏  举报