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

53 篇文章 3 订阅
25 篇文章 0 订阅

问题描述:

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

输入字母,数字,符号都没问题:
在这里插入图片描述
输入中文时问题就出来了:
每个拼音字母都触发了change,甚至输入法里的nin’hao 把拼音分开的字符也会触发。
在这里插入图片描述
基础代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</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>Document</title>
</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>

这回只执行了一次:
效果图

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;

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
<h3>回答1:</h3><br/>onchange和oninput事件监听函数的不同类型。onchange监听的是元素值(input、select、textarea等)的改变并提交前的事件,而oninput监听的是元素值的实时改变事件,即每当用户输入一个字符都会触发oninput事件。 <h3>回答2:</h3><br/>onchange 和 oninput 是两种常见的 JavaScript 事件类型,它们都能够监听到表单元素的值发生变化的时候触发事件。但是,它们之间还是有很多区别的。 onchange 是在元素的值发生改变并且失去焦点的时候触发事件。也就是说,当用户在输入框中输入了一些内容,然后点击别的地方或者按下 Tab 键切换焦点时,onchange 事件才会被触发。如果用户在输入框中输入内容后直接点击提交按钮,那么 onchange 事件不会被触发。而且,如果使用 JavaScript 修改表单元素的值,也不会触发 onchange 事件。 oninput 事件则不同,它在用户输入的时候就会触发事件,每当表单元素的值发生改变就会触发一次。也就是说,只要用户输入了任何一个字符,oninput 事件就会被触发。如果使用 JavaScript 修改表单元素的值,oninput 事件也会被触发。 因此,从上面的解释可以看出:onchange 适用于需要用户在输入完成之后再进行处理的情况,而 oninput 更加实时,适用于一些需要及时反馈的场景,例如实时搜索、即时更新等等。 在实际的开发中,我们需要根据具体的需求来选择使用 onchange 还是 oninput 事件,以便更好地满足用户需求。 <h3>回答3:</h3><br/>onchange和oninputJavaScript中两个常见的事件处理器。它们在用户输入文本的时候都会被触发,但是它们有不同的特点和用法。 首先,onchange事件处理器是在输入元素(如文本框或下拉菜单)中的值发生变化并且失去焦点时触发的。换句话说,当用户在输入元素中改变其值,并将焦点从该元素移开时,它才会被触发。因此,onchange事件处理器通常用于捕获元素的值的最终版本,即在用户更改之后。 相反,oninput事件处理器是在输入元素中的值发生任何变化时都会被触发的。每一次键盘按下、复制、粘贴、删除都会触发事件。因此,oninput事件处理器通常用于捕获用户正在输入的内容,并在其输入的时候进行实时响应。 此外,onchange事件处理器一般只适用于像下拉菜单这样的输入元素,因为这些元素存在一个明确的选项列表,而且只有在用户准备好提交其选择时才会触发。而oninput事件处理器适用于文本框等自由文字输入元素,因为用户可以在任何时候输入或更改他们的值。 在总体上,onchange和oninput事件处理器都是用于捕获用户输入行为的工具。只要开发人员了解它们如何工作和何时使用,就可以使用它们来满足不同的需求和优化用户体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

崽崽的谷雨

漫漫前端路,摸爬滚打

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值