前端防重复提交(节流函数)

Posted zhengyulu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端防重复提交(节流函数)相关的知识,希望对你有一定的参考价值。

应用情景

经典使用情景: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="width: 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>

总结
前两种方式实现起来比较方便,而后两种实现起来相对比较繁琐,如果是为了防止事件的多次触发,建议使用闭包,如果是表单提交,适度使用后两种比较稳妥。

以上是关于前端防重复提交(节流函数)的主要内容,如果未能解决你的问题,请参考以下文章

JS函数节流和函数防抖问题分析

函数防抖VS函数节流

前端进击的巨人:浅谈函数防抖与节流

手写防抖节流

手写防抖节流

js前端性能优化之函数节流和函数防抖