입력 상자 입력 이벤트 구성 시작 및 구성 종료의 마법 효과

현상:

입력 방법을 입력하면 切换到中文다음과 같이 병음 프로세스 중에 oninput 이벤트도 트리거됩니다.

const Demo=()=>{
    
    
  const [value,setValue]=useState("");
  return (
    <>
      <input onInput={
    
    (e)=>{
    
    
        console.log("value:",e.target.value)
        setValue(e.target.value)
      }}/>
      <span>{
    
    value}</span>
    </>
  )
}

여기에 이미지 설명을 삽입하세요

이로 인해 발생하는 문제점 중 하나는 중국어를 입력하는 과정에서 입력창이 흔들릴 수 있다는 점인데, 이 문제를 해결하는 방법은 무엇인가요 ?
입력은compositionstart와compositionend라는 두 가지 이벤트를 제공합니다. MDN 링크를 참조하세요.

여기에 이미지 설명을 삽입하세요

해결책:

위 코드를 최적화하세요.

const Demo = () => {
    
    
  const [value, setValue] = useState("");
  return (
    <>
      <input
        onCompositionStart={
    
    (e) => {
    
    
          console.log("onCompositionStart")
          e.target.composing = true
        }}
        onCompositionEnd={
    
    (e) => {
    
    
          console.log("onCompositionEnd",e.target.value)
          if(!e.target.composing)return;
          (e.target.composing = false)
          setValue(e.target.value);
        }}
        onInput={
    
    (e) => {
    
    
          if(e.target.composing) return;
          console.log("value:", e.target.value);
          setValue(e.target.value);
        }}
      />
      <span>{
    
    value}</span>
    </>
  );
};

여기에 이미지 설명을 삽입하세요
여기에 이미지 설명을 삽입하세요
이로써 중국어 입력시 입력창 문제가 완전히 해결되었습니다.


위의 솔루션은 실제로 vue 소스 코드 v-model 명령이 구현될 때 입력 상자 이벤트 처리에서 비롯됩니다.

const directive = {
    
    
  inserted (el, binding, vnode, oldVnode) {
    
    
    if (vnode.tag === 'select') {
    
    
      // #6903
      if (oldVnode.elm && !oldVnode.elm._vOptions) {
    
    
        mergeVNodeHook(vnode, 'postpatch', () => {
    
    
          directive.componentUpdated(el, binding, vnode)
        })
      } else {
    
    
        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) {
    
    
        el.addEventListener('compositionstart', onCompositionStart)
        el.addEventListener('compositionend', onCompositionEnd)
        // 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)
        /* 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)
}

이것으로부터 우리는 vue 프레임워크를 작성할 때 squid가 얼마나 신중했는지 알 수 있으며 이러한 세부 사항이 고려되었습니다.

참조 링크:
입력 상자 이벤트 구성 시작 및 구성 끝의 마법적인 사용

Supongo que te gusta

Origin blog.csdn.net/yexudengzhidao/article/details/131555047
Recomendado
Clasificación