前端面试题:输入框中文如何防抖

一、什么是防抖

防抖是指当一个事件触发的时候, 为防止频繁触发事件, 设置定时器,以达到一种 频繁触发期间不处理, 只有当最后一次连续触发结束以后才处理

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)
}

本文结束,内容部分来自网络。作者职场小白一枚,望大佬路过时,不吝赐教/抱拳。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值