JS函数节流
关于函数节流,网上资料也是挺多了。
今天实际写了下,应用场景是在向文本框输入文字时,与后台交互,验证输入的用户名是否已存在。
HTML:
<input type="text" id="myValue" />
JS:
var input = document.querySelector('#myValue');
function conText(e) {
console.log(e.target.value);
//ajax操作......
}
function throttle(method, delay) {
var timer = null;
return function() {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
method.apply(context, args);
}, delay);
}
}
input.onkeyup = throttle(conText, 1000);
以上代码主要思路很简单,只要执行keyup事件,就会清除上一次设置的定时器。这里延时设置为1秒,也就是说当1秒内没有keyup发生,才执行需要的函数,1秒内发生了keyup事件,则清空上一次的定时器。这样很好避免了连续输入时向服务端发送过多请求,从而缓解了压力。
具体看下代码。
throttle函数中定义了一个timer为null,这个值是用来设置定时器的。这个函数的返回值是一个function。所以其实可以看作:
input.onkeyup = function() {
var context = this, args = arguments;
//......
}
timer显然不能在function里定义,否则每次触发keyup事件,相当于变成了一个新的timer,所以需要在throttle中定义,这样可以保存住timer的值,也不会使得timer变成一个全局变量。
至于var context = this, args = arguments
这两个参数的意义就比较好理解了。context是保存当前的this,对应的就是那个input元素,因为进入下一个function后,this会指向window对象,所以需要提前取用这个this。
args就是函数的参数,在这里对应的应该就是keyboard event。
说得更明白一点。
input.onkeyup = function(e) {
console.log(e);
}
args中存着的就是这个e,
throttle中的method对应的是conText函数。conText中有一个参数e,所以这边args就是为了给conText传递参数而存在。也就是后面的method.apply(context, args); 这一句。
运用apply修改了conText的this指向,使其指向input元素,同时把args作为参数传给了它(就是conText里的那个e)。