一、什么是防抖
防抖是指当一个事件触发的时候, 为防止频繁触发事件, 设置定时器,以达到一种 频繁触发期间不处理, 只有当最后一次连续触发结束以后才处理
function debounce(cb,wait){
let timer
return function(){
clearTimeout(timer)
timer = setTimeout(()=>cb(),wait)
}
}
二、中文输入问题
中文输入时在打拼音时(此时input内还没有填入真正的内容),会首先触发compositionstart,然后每打一个拼音字母,触发compositionupdate,同时触发input事件,最后将输入好的中文填入input中时触发compositionend。
触发compositionstart时,文本框会填入 “虚拟文本”(待确认文本),同时触发input事件;在触发compositionend时,就是填入实际内容后(已确认文本)
<body>
<input id="input">
</body>
<script>
let input = document.getElementById('input')
input.addEventListener('input',inputChange)
input.addEventListener('compositionstart',compositionstart)
input.addEventListener('compositionupdate',compositionupdate)
input.addEventListener('compositionend',compositionend)
function compositionstart(){
console.log('compositionstart')
}
function compositionupdate(){
console.log('compositionupdate')
}
function compositionend(){
console.log('compositionend')
}
function inputChange(){
console.log('input')
}
</script>
三、输入框中文如何防抖
我们在工作中最常见的标签就是input,我们常常需要对输入框的进行各种处理,如渲染到页面、搜索等。此时我们习惯监听input事件,但是输入中文时就存在各种问题。此时我们就需要放弃监听input事件,转而去监听compositionend事件。
值得一提的是,当我们使用vue的双向绑定指令,也就是v-model时,不需要去考虑这个问题,在vue的源码中,已经进行了相同的处理。
export default {
inserted (el, binding, vnode) {
if (vnode.tag === 'select') {
setSelected(el, binding, vnode.context)
el._vOptions = [].map.call(el.options, getValue)
} else if (vnode.tag === 'textarea' || isTextInputType(el.type)) {
el._vModifiers = binding.modifiers
if (!binding.modifiers.lazy) {
// Safari < 10.2 & UIWebView doesn't fire compositionend when
// switching focus before confirming composition choice
// this also fixes the issue where some browsers e.g. iOS Chrome
// fires "change" instead of "input" on autocomplete.
el.addEventListener('change', onCompositionEnd)
if (!isAndroid) {
el.addEventListener('compositionstart', onCompositionStart)
el.addEventListener('compositionend', onCompositionEnd)
}
/* istanbul ignore if */
if (isIE9) {
el.vmodel = true
}
}
}
}
}
//...
function onCompositionStart (e) {
e.target.composing = true
}
function onCompositionEnd (e) {
// prevent triggering an input event for no reason
if (!e.target.composing) return
e.target.composing = false
trigger(e.target, 'input')
}
function trigger (el, type) {
const e = document.createEvent('HTMLEvents')
e.initEvent(type, true, true)
el.dispatchEvent(e)
}
本文结束,内容部分来自网络。作者职场小白一枚,望大佬路过时,不吝赐教/抱拳。