oninput防抖

来一波input防抖,以及处理输入法的问题

惯例敬你一杯毒鸡汤:
虽然现在累得像条狗,但不久后你就会有所收获。收获到一个真理:狗都没我累!吼吼~

一步步来吧,先说一下input防抖,首先要了解这些东西:

1、oninput事件

话说input元素有一个原生的事件叫oninput,这个事件会在用户在input中输入时触发。目前基本支持主流的所有浏览器,IE浏览器需要9.0版本以上都支持,不过IE9虽然说支持,但是支持的不大好,无法响应一些比如删除之类的操作,用的时候要注意。

2、为啥会抖

在前端开发中,很多地方会需要input搜索功能,要求是用户在输入的过程中进行模糊查询。这个功能很常见,像百度谷歌等搜索都是会进行模糊查询的。

这时候会出现一个问题,就是用户在input框输入的时候,我们监听的input事件是一旦输入框内容发生改变就触发我们绑定的回调函数,而我们的回调函数中很可能会加入一些异步请求之类比较复杂的操作,在用户未完全输入完成,我们就执行了很多次回调请求。既耗时又影响性能。

这个就是传说中的input抖动了哈。

3、怎么防抖

说白了,input抖动就是太灵敏了,执行回调的次数过于频繁了,那么思路就是怎么不让它执行的这么频繁呗。所以原理就是在输入内容时不立即执行,而是延时触发回调函数的执行。如果继续输入,则上次的不再执行。
上代码:

<input id="input1" oninput="callback(value)">
let timer = null; // 定义一个全局的定时器对象变量
function callback(val) {
	clearTimeout(timer); // 清除上一个定时器
	timer = setTimeout(function () {
		console.log(val); // 这里是我们的请求之类的操作,我这里做个打印,方便看结果
	}, 1000);
}

执行结果:
在这里插入图片描述
可以发现,已经做到了不是每次输入都执行了。

当然也可以这么写:

<input id="input1">
let timer = null; // 定义一个全局的定时器对象变量
let dom1 = document.getElementById('input1'); // 拿到input元素对象
dom1.addEventListener('input', function () { // 监听其input事件
	let e = event || document.event;
	clearTimeout(timer); // 清除上一个定时器
	timer = setTimeout(function () {
		console.log(e.target.value);
	}, 1000);
});

在这里插入图片描述

防抖完成,那么再来说一下输入中文搜索的问题吧。

之所以我们可以输入汉字,是因为IME。
IME (Input Method Editor) 输入法编辑器。
意思就是,我们切换输入法,输入中文,韩文,日文等等的应用程序。简体中文的 IME 将用户的击键转换为汉字。 也就是说,如果我们的操作系统不支持IME,我们就无法输入汉字了,哈哈,题外话,回来~

先看个现象,我们再input搜索的时候,用拼音输入汉字:
在这里插入图片描述
会发现,oninput事件会把我们输入的汉字拼音都给监听触发回调了。但这不是我们希望发生的,所以需要我们做一些处理。

这时候就不得不提几个原生事件了:compositionstart、compositionupdate、compositionend

  • compositionstart:事件触发于IME开始时,即你使用输入法输入开始时触发,只触发一次。
  • compositionupdate:在compositionstart 事件触发后触发,输入数据发生改变的时候会实时触发。
  • compositionend:IME完成或取消时触发,即你使用输入法输入完成后触发。

有了上面这几个时间,就可以处理中文输入的问题了。
上代码:

let imeFlag = true; // 创建一个是否处于输入法输入状态的标识
let timer = null; // 防抖定时器

let dom1 = document.getElementById('input1'); // 获取input元素

dom1.addEventListener('compositionstart', function () {
	imeFlag = true; // 处于输入法状态,设置标识为true
});

dom1.addEventListener('compositionend', function () {
	let e = event || document.event;
	imeFlag = false; // 输入法输入结束后,设置标识为false
	callback(e.target.value); // 输入法输入结束后,调用我们oninput的回调函数
});

dom1.addEventListener('input', function () {
	let e = event || document.event;
	if (!imeFlag ) { // 处于输入法输入时,不予处理。
		callback(e.target.value);
	}
});

function callback(val) {
	clearTimeout(timer); // 清除上一个定时器
	timer = setTimeout(function () {
		console.log(val);
	}, 1000);
}

执行后:
在这里插入图片描述
现在已经解决了所有的问题了!

在这里插入图片描述
啦啦啦~

没有错,老毛病又犯了,继续磨叨磨叨:

兼容文本输入的方法,目前知道的有很多哈,比如oninput,onkeypress,onkeyup,onkeydown还有比较常用的onchange和onpropertychange。

估计这些大家都用过,反正我是都用过,但是没有系统的区分过这堆东西。嘿嘿,那就把它们放一起吧。

<input onkeydown="console.log('onkeydown')"
	   onkeypress="console.log('onkeypress')"
	   oninput="console.log('oninput')"
	   onkeyup="console.log('onkeyup')"
	   onchange="console.log('onchange')"
	   onpropertychange="console.log('onpropertychange')">

打印结果:(Google,火狐,IE9以上版本浏览器)
在这里插入图片描述
打印结果:(IE8浏览器)
在这里插入图片描述
很直观哈:

  • onkeydown: 键盘按下的时候触发。
  • onkeypress: 键盘按下的时候触发,在onkeydown之后触发。
  • oninput: 输入框输入数据时触发。
  • onpropertychange: 输入框输入数据时触发。
  • onkeyup: 放开键盘按键的时候触发。
  • onchange: 鼠标焦点离开输入框且输入框数据发生变化时触发。

这中间就有一些有意思的地方了哈,比如:
1、onkeydown和onkeypress有啥区别?

onkeydown是任意按键按下都会触发。而且捕获的 keyCode 不区分字母大小。
onkeypress只兼容字母数字等按键,而一些系统功能键不会触发。捕获的 keyCode 是区分大小写的。(系统功能键包括:ctrl,shift,enter,以及箭头键等等)。

这么看,突然就会有种了解了定义这些事件的大神的想法了。大神的理解应该是,keydown用来监听按键操作,而keypress用来监听按键内容。棒棒~

2、oninput和onpropertychange只是浏览器版本支持的不同的区别吗?

看着是!

哈哈,这么回答会不会被打死?

其实不是的啊,如果仔细研究onpropertychange,你会发现它真棒!
通过字面意思,可以看出是在监听property(属性)的变化。也就是onpropertychange监听的是元素的property属性,并不只局限于value,也可以监听其他标准属性值。比如name,class等等……

oninput显然是不能监听元素属性的,但是onpropertychange任何属性的改变都可以触发该事件。这么好的东西,哈哈,只有IE浏览器兼容,吼吼~

3、onkeydown和onkeyup始终会在一起触发吗?

onkeyup和onkeydown基本上是一对儿的。但是如果onkeydown的时候,将光标,就是鼠标焦点移走了,那么onkeyup就监听过不到了。比如说你按了tab键~~,哈哈,keyup就被抛弃了。

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值