应用情景
经典使用情景:js的一些事件,比如:onresize、scroll、mousemove、mousehover等;
还比如:手抖、手误、服务器没有响应之前的重复点击;
这些都是没有意义的,重复的无效的操作,设置对整个系统的影响还可能是致命的,所以我们要对重复点击的事件进行相应的处理!
节流函数
所谓的节流函数顾名思义,就是某个时刻限制函数的重复调用。
同样节流函数也是为了解决函数重复提交的问题,而防止重复提交的方法,不止节流函数一种实现。
方法汇总
本文整理了我在工作实践当中,觉的防止js重复提交,比较好用的方法,在这里和大家分享一下。
一、setTimeout + clearTimeout(节流函数)
本文提供两种实现方式:普通节流函数和闭包节流函数
二、设定flag/js加锁
三、通过disable
四、添加浮层比如loading图层防止多次点击
具体实现
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div style=" 200px; height: 100px; background: red;" id="Test">hahaahahhah</div> </body> <script> //------------------------闭包节流函数------------------------ var throttle = function (fn, delay) { var timer = null; return function () { var args = arguments; //参数集合 clearTimeout(timer); timer = setTimeout(function () { fn.apply(this, args); }, delay); } } function postFun(name) { console.log(1) } var t = throttle(postFun, 1000); document.getElementById('Test').onclick = function(){ t(); } //------------------------普通节流函数------------------------ function throttle(fn, delay) { if (fn._id) { clearTimeout(fn._id); } fn._id = window.setTimeout(() => { fn(); fn._id = null; }, delay); } function postFun() { console.log(1) } document.getElementById('Test').onclick = function(){ throttle(postFun, 1000); } //------------------------简洁节流函数方法------------------------ var timer = null; document.getElementById('Test').onclick = function(){ if(!timer) clearTimeout(timer); timer = setTimeout(function(){ console.log(1) },1000) } //设定flag/js加锁 var lock = false; jQuery("#submit").on('click', function () { if (lock) { return false; } lock = true; jQuery.post(url, data, function (response) { //TODO:业务代码 lock = false; }); }); </script> </html>
总结
前两种方式实现起来比较方便,而后两种实现起来相对比较繁琐,如果是为了防止事件的多次触发,建议使用闭包,如果是表单提交,适度使用后两种比较稳妥。