input事件中文触发多次问题研究
我们在网页中经常会遇到实时搜索的情况,或者其他类似需要input实时响应的问题,一般情况下,我们是利用input和propertychange事件来监听input内容的变化来响应,但是有一个问题就是当输入汉字的时候,可能我们要输入 ‘实时’ 的时候,我们的input框中会出现 'shishi'直到我们的空格才会变成 '实时',这也就意味着我们依次响应了 's','sh','shi','shis','shish','shishi','实时',前面的结果明显不是我们需要的 ,造成了我们很多次无用的提交,如果是接口请求,那更要命,多发了好多次请求。
最早之前有一个稍微能改善的解决方案就是配合一个定时器延时执行,这样能减少请求次数,但是这个减少是不分情况的减少 ,还是治标不治本。
今天偶然看到几个事件,发现可以完美解决这种问题。我们来看一下这几个事件
compositionstart , compositionupdate ,compositionend
compositionstart 官方解释 : 触发于一段文字的输入之前(类似于 keydown 事件,但是该事件仅在若干可见字符的输入之前,而这些可见字符的输入可能需要一连串的键盘操作、语音识别或者点击输入法的备选词),通俗点,假如我们要输入一段中文,当我们按下第一个字母的时候触发 。
相应的compositionupdate在我们中文开始输入到结束完成的每一次keyup触发。
而compositionend则在我们完成当前中文的输入触发 。
正题来了,通过上面的事件我们就可以完美的解决中文输入的响应问题了,从compositionstart触发开始,意味着中文输入的开始且还没完成,所以此时我们不需要做出响应,在compositionend触发时,表示中文输入完成,这时我们可以做相应事件的处理。
所以我们可以设置一个变量,或者给input定义一个属性,在compositionstart到compositionend之间对input事件不做出响应。看以下代码
$('input').on({
input : function(e){
var flag = e.target.isNeedPrevent;
if(flag) return;
response()
},
compositionstart : function(e){
e.target.isNeedPrevent = true ;
},
compositionend : function(e){
e.target.isNeedPrevent = false;
}
})
function response(){
$('div').append('<p>事 件触发</p>')
}
我们通过compositionstart,compositionend事件来设置flag,判断是否正在进行输入中文以控制input事件的响应,看上去没有问题,但实际执行时会发现在谷歌浏览器中input执行顺序要先于compositionend,火狐执行顺序正常,但compositionend会响应两次。这就导致谷歌浏览器中输入汉字不会响应input事件。当然也可以在compositionend事件中再执行一次response事件,这样的问题是在火狐浏览器中会多执行一次response,显然不是最优方案。
经过试验,发现keyup和compositionend事件执行顺序在各大浏览器都保持一致,于是我们改成如下代码:
$('input').on({
keyup : function(e){
var flag = e.target.isNeedPrevent;
if(flag) return;
response()
},
compositionstart : function(e){
e.target.isNeedPrevent = true ;
},
compositionend : function(e){
e.target.isNeedPrevent = false;
}
})
function response(){
$('div').append('<p>事 件触发</p>')
}
这样在各个浏览器基本保持一致了(兼容compositionstart的浏览器)。但是keyup有一个问题,比如通过鼠标复制粘贴的时候并不相应keyup事件,所以上面的事情我们还需要再优化下,keyup相应按键事件,input响应除了keyup之外的变化事件。代码如下
$('input').on({
keyup : function(e){
var flag = e.target.isNeedPrevent;
if(flag) return;
response() ;
e.target.keyEvent = false ;
},
keydown : function(e){
e.target.keyEvent = true ;
},
input : function(e){
if(!e.target.keyEvent){
response()
}
},
compositionstart : function(e){
e.target.isNeedPrevent = true ;
},
compositionend : function(e){
e.target.isNeedPrevent = false;
}
})
function response(){
$('div').append('<p>事 件触发</p>')
}
从目前需求可以完全实现了。
参考文章:
https://developer.mozilla.org/zh-CN/docs/Web/Events/compositionstart
input事件中文触发多次问题研究的更多相关文章
- input输入中文时,拼音在输入框内会触发input事件的问题。
问题描述: 监听文本输入框的input事件,在拼写汉字(输入法)但汉字并未实际填充到文本框中(选词)时会触发input事件,如图: 需要完成的需求就是在输入阶段不触发input中的事件,选词之后文字落 ...
- input、textarea等输入框输入中文时,拼音在输入框内会触发input事件的问题
监听文本输入框的input事件,在拼写汉字(输入法)但汉字并未实际填充到文本框中(选词)时会触发input事件,如图: 但是在很多情况下,只需要输入到输入框的中文字符. 解决办法: 通过查阅资料得知在 ...
- input事件以及中文输入法的处理
在项目的开发过程中,相信大家都处理过监听用户输入的事情,一般我们会用到onkeyup.onkeydown.onkeypress.onchange.oninput事件,虽然都很熟悉了,但是还是有必要巩固 ...
- compositionEnd 和 input 事件(中文输入法问题)
网上用 compositionstart + compositionend + input 解决中文输入法问题的办法 node.addEventListener('compositionstart', ...
- label标签内含有input元素,点击事件会触发两次
**label标签内含有input元素,点击事件会触发两次** 如果你的结构是label内写input实现点击文字时候input也有相应.并且,把事件设置在了label上,那么就会执行两次了. //h ...
- vant 使用field组件加载页面就触发input事件的坑,已解决
使用vant的时候,遇到一个坑,加载组件就自动触发input事件,input事件里写了验证,导致已加载就验证错误 原因:v-model绑定的时候写的是null, filed组件接收的时候把他转换成空字 ...
- input 事件与汉字输入法:使用compositionend事件解决
input 事件与汉字输入法:使用compositionend事件解决 在使用<input type="text">的input事件的时候 会遇到中文输入法的" ...
- input事件与change事件
输入框的change事件: 必须等到输入框失去焦点的时候才会触发,鼠标在空白的地方点一下: 输入框的input事件: 在输入内容变化的同时,实时的触发,不需要等到失去焦点.
- HTML5 input事件检测输入框变化
之前一直用change事件来监听输入框内容是否发生变化,只有当输入框失去焦点时才会触发,没想到html5还有个input事件,只要输入框内容发生变化就会立即触发,既然有这么好的东西我们干嘛放着不用呢, ...
随机推荐
- Jmeter+Ant+Jenkins接口自动化测试(一)_环境部署
前言: 2017年最后一个月份,今天抽出时间把之前的一些记录分享出来,也为今年画上个简单的句号吧,无论好与坏,无论成功与失败,简单的记忆,不要留下点点空白. 特别提示: 知识是用来分享的,但是也要尊重 ...
- 不解释,分享这个base.css
@charset "utf-8"; /*! * @名称:base.css * @功能:1.重设浏览器默认样式 * 2.设置通用原子类 */ /* 防止用户自定义背景颜色对网页的影响 ...
- 一点解决版本冲突的应急思路、怎样在所有jar包文件中搜索冲突的方法?
maven是一个很好的项目管理工具,你可以轻松的定义一个引用,从而达到使用别人写好的库的作用.且maven可以轻松地和jenkins配合,从而使打包部署变得更容易. 但是也因为这样,我们变得更傻瓜了, ...
- Python Tkinter模块 Grid(grid)布局管理器参数详解
在使用Tkinter模块编写图像界面时,经常用到pack()和grid()进行布局管理,pack()参数较少,使用方便,是最简单的布局,但是当控件数量较多时,可能需要使用grid()进行布局(不要在同 ...
- CSS 鼠标样式大全
cursor是CSS中用于定义鼠标在元素标签上的显示样式,如常用的手型鼠标样式 cursor: pointer; 也可以通过url网址指定扩展名一般为.cur的鼠标图片文件. 名称 属性代码 描述 默 ...
- JS 监听微信、支付宝等移动app及浏览器的返回、后退、上一页按钮的事件方法
在实际的应用中,我们常常需要实现在移动app和浏览器中点击返回.后退.上一页等按钮实现自己的关闭页面.调整到指定页面或执行一些其它操作的需求: 那在代码中怎样监听当点击微信.支付宝.百度糯米.百度钱包 ...
- [补充资料] 手动搭建 Cloudera 集群
本课主题 集群搭建 设置 Web 服务器 启动 ClouderManager 登入 Cloudera Manager 引言 这部份是一个补充资料,记录如何安装 Cloudera 服务器 集群搭建 查看 ...
- 【APS.NET 框架系列】浅谈ASP.NET 框架
本篇文章稍微偏原理且底层,有一定难度和且比较晦涩. 本篇文章主要是从广度上概括一下,具体的更细粒度的,会在后续的文章中,结合具体的Demo实例分析. 一 .NET框架概述 1.作用:提供了基于. ...
- 深入理解ES6之—块级绑定
var声明与变量提升 使用var关键字声明的变量,无论其实际声明位置在何处,都会被视为声明于所在函数的顶部(如果声明不在任意函数内,则视为在全局作用域的顶部).这就是所谓的变量提升. 块级声明 块级声 ...
- flush table with read lock的轻量级解决方案[原创]
为什么要使用FTWRL MySQL dba在日常工作中,数据备份绝对是工作频度最高的工作内容之一.当你使用逻辑方式进行备份(mydumper,mysqldump)或物理方式进行备份(percona ...