input 输入中文,高频触发 onchange和oninput事件(CompositionEvent API解决)

问题描述:

input onchange和oninput 事件输入中文时高频触发。

输入字母,数字,符号都没问题:
input 输入中文,高频触发 onchange和oninput事件(CompositionEvent API解决)_第1张图片
输入中文时问题就出来了:
每个拼音字母都触发了change,甚至输入法里的nin’hao 把拼音分开的字符也会触发。
input 输入中文,高频触发 onchange和oninput事件(CompositionEvent API解决)_第2张图片
基础代码:

DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Documenttitle>
head>

<body>
  <input type="text" id="name">
body>
<script>
  // 1. 获取元素
  var inp = document.getElementById('name');
  console.log(inp);
  // 2. 添加事件
  inp.addEventListener('input', function () {
    // 3. 获取输入的内容
    var value = inp.value;
    // 4. 输出内容
    search(value);
  });

  // search 是请求接口
  function search(value){
    
  }
script>

html>

解决方案:

解决方案就是用 CompositionEvent 事件里的onCompositionStart 和onCompositionEnd 解决:

  • onCompositionStart 事件在用户开始使用输入法输入时触发。在这个事件中,你可以禁用或延迟处理 onChange 事件,以避免在输入过程中重复触发。

  • onCompositionUpdate 事件在用户正在使用输入法输入时触发。在这个事件中,你可以更新输入框的值,但通常不会在这个事件中执行一些重要的操作。

  • onCompositionEnd 事件在用户完成使用输入法输入时触发。在这个事件中,你可以处理最终的输入结果,更新输入框的值,并执行一些重要的操作,如发送请求、更新页面等。
    这些事件主要用于处理复合字符输入,例如在中文输入法中,用户可能会输入一段拼音,然后选择对应的汉字组成词语,最后将整个词语输入到输入框中。这个过程中, onCompositionStart 会在输入开始时触发, onCompositionUpdate 会在输入过程中触发, onCompositionEnd 会在输入结束时触发。
    通过使用这些事件,我们可以更好地控制输入法输入的过程,避免在输入中文拼音时多次触发 onChange 事件,并在最终输入完成时触发相应的处理逻辑。

思路:
1.定义一个全局变量 isComposing,当 onCompositionStart 正在输入时给其赋值 为true。
2.onCompositionEnd 输入结束时,给其设置成 false。
3.然后在 change和input里判断这个值,等于true时不执行搜索即可。

具体代码如下:
需要注意的是在 compositionend 事件触发时,浏览器会继续触发 input 事件,所以 search 函数会在 input 事件中被执行。

DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Documenttitle>
head>

<body>
  <input type="text" id="name">
body>
<script>
  var inp = document.getElementById('name');
  var isComposing = false;
  inp.addEventListener('compositionstart', function () {
    isComposing = true;
    console.log('中文开始输入');
  })
  inp.addEventListener('compositionend', function () {
    isComposing = false;
    console.log('中文结束输入');
    search(inp.value);
  })
  inp.addEventListener('input', function () {
    if (isComposing) {
      return;
    }
    var value = inp.value;
    // 执行搜索逻辑
    search(value);
  });
  function search(value) {
    console.log(value, "执行搜索");
    // 实际的搜索逻辑
  }
script>

html>

这回只执行了一次:
input 输入中文,高频触发 onchange和oninput事件(CompositionEvent API解决)_第3张图片

MDN CompositionEvent API

react 里则是使用onCompositionEnd、onCompositionStart解决。思路写法是一样的转换成react语法就行。

代码如下:

import React, { useState} from "react";

function Inp() {
  //input值
  const [value, setValue] = useState("");
  //是否输入完成值
  const [isComposing, setIsComposing] = useState(false);

  const handleCompositionEnd = (e) => {
    setIsComposing(false);
    search();
  };

  const handleCompositionStart = (e) => {
    setIsComposing(true);
  };

  const handleChange = (e) => {
    let val = e.target.value;
    // console.log(val);
    setValue(val);
    if (isComposing) return;
    search();
  };

  const search = () => {
    console.log(value,"执行搜索");
  };
  return (
    <div className="sss">
      <input
        type="text"
        onCompositionEnd={handleCompositionEnd}
        onCompositionStart={handleCompositionStart}
        onChange={handleChange}
        value={value}
      />
    div>
  );
}
export default Inp;

你可能感兴趣的:(js,前端,React,javascript,前端)