JS函数节流

背景:在前端开发中,有时会为页面绑定resize事件,或为一个页面元素拖拽事件(其核心就是绑定mousemove)在一个正常操作中也有可能在一个短时间内触发非常多次事件绑定程序,而DOM操作是很消耗性能的,如果为这些事件绑定一些操作DOM节点的操作的话就会引发大量的计算,在用户看来页面可能就一时间没有响应,这个页面就变卡变慢了,甚至在IE下,如果绑定的resize事件进行较多DOM操作,其高频率可能直接就使得浏览器崩溃。
函数节流简单讲就是让一个函数无法在很短的时间间隔内连续调用,只有当上一次函数执行后过了你规定的时间间隔,才能进行下一次该函数的调用。
函数节流原理:用定时器,当触发一个事件时,先setTimout让这个事件延迟一会再执行,如果在这个时间间隔内又触发了事件,那我们就clear掉原来的定时器,再setTimeout一个新的定时器延迟一会执行。
优缺点:
《JavaScript高级程序设计》中介绍的函数节流

function throttle(method,context){
    clearTimeout(method,tId);
    method.tId=setTimeout(function(){
        method.call(context);
    },100);
}
//调用
window.onresize=function(){
    throttle(myFunc);
}

//法二:
var throttle=function(fn,delay){
    var timer=null;
    return function(){
        var context=this,args=arguments;
        clearTimeout(timer);
        timer=setTimeout(function(){
            fn.apply(context,args);//context调用fn的方法,指针指向了fn
        },delay);
    }
}
//调用
window.onresize=throttle(myFunc,100);

函数节流让一个函数只有在你不断触发后停下来歇会才开始执行,中间你操作得太快它直接无视你。这样做就有点太绝了,resize一般还好,但假如写一个拖拽元素位置的程序,然后直接使用函数节流,会发现你拖动时元素是不动的,你拖完了它直接闪到终点去,所以进行优化:

var throttleV2=function(fn,delay,mustRunDelay){
    var timer=null;
    var t_start;
    return function(){
        var context=this,args=arguments,t_curr=+new Date();
        clearTimeout(timer);
        if(!s_start){
            t_start=t_curr;
        }if(t_curr-t_start>=mustRunDelay){
            fn.apply(context,args);
            t_start=t_curr;
        }else{
            timer=setTimeout(function(){
                fn.apply(context,args);
            },delay);
        }
    }
}
window.onresize=throttleV2(myFunc,50,100);

解析:50ms的间隔内连续触发的调用,后一个调用会把前一个调用的等待处理掉,但每隔100ms至少执行一次。
1.具有节流效果的tab切换案例:

var timer=null;
function tab(obj){
    var target = document.getElementById(obj);
    var spans = target.getElementsByTagName("span");
    var lis = target.getElementsByTagName("li");
    for(var i=0;i<spans.length;i++)
    {

        spans[i].onmouseover = function(num){
            return function(){
                clearTimeout(timer);
                timer=setTimeout(function(){
                    for(var j=0; j<spans.length;j++)
                    {
                        spans[j].className = "";
                        lis[j].className = "";
                    }
                    spans[num].className = "current";
                    lis[num].className = "show";
                },300);
            }
        }(i);
        spans[i].onmouseout=function(){
            clearTimeout(timer);
        }
    }

}
tab("one");

2.屏幕缩放节流案例:

<body>
    <div id="demo"></div>
</body>
</html>
<script>
    var demo=document.getElementById("demo");
    var num=0;
    window.onresize=throll(function(){
        demo.innerHTML=window.innerWidth || document.documentElement.clientWidth;
        num++;
        alert(num);
    },300);
    function throll(fn,delay){
        var timer=null;
        return function(){
            clearTimeout(timer);
            timer=setTimeout(fn,delay);
        }
    }
</script>
时间: 2024-11-05 02:01:18

JS函数节流的相关文章

Underscore.js 函数节流简单测试

函数节流在日常的DOM界面数据交互中有比较大的作用,可以减少服务器的请求,同时减少客户端的内存影响 Underscore.js  本省就包含了函数节流的处理函数 _.throttle 和 _.debounce 简单的测试使用如下: 需要使用的类库为jquery  .Underscore 测试的方法为:mousemove 事件 测试页面代码如下: <!DOCTYPE html > <html> <head> <script src="jquery-1.11

js 函数节流

在JS中,函数的调用大多数都是由用户主动调用触发,但是在有的事件中,比如mousemove.window.onresize.touchmove中,函数的调用次数会非常频繁,从而消耗浏览器大量的内存空间,造成浏览器卡顿甚至假死的问题.所以函数节流的目的就是减少函数在这些事件中的调用次数,从不可控制到可控. 函数节流的实现方式有很多中,通用的原理就是使用setTimeout函数,延迟执行事件处理函数,在没有执行这个函数前,再次调用它时都忽略,具体实现方式如下: /* * 节流函数 * fn 事件中实

js函数节流(解决频繁触发函数的性能问题)

? JS中的函数大多数情况下都是由用户主动调用触发的,但在一些少数情况下,函数的触发不是由用户直接控制的.在这些场景下,函数有可能被非常频繁地调用,而造成大的性能问题. 函数被频繁调用的场景 键盘事件: 参考百度的搜索框没输入一个字母就发送一次Ajax请求开销很大 通过下面的函数可以实现性能的优化,每过500ms 触发一次事件 var isClick; $( 'text' ).on( 'keydown', function () { clearTimeout( isClick ); isClic

js函数节流和防抖

// 函数节流 var canRun = true; document.getElementById("throttle").onscroll = function(){ if(!canRun){ // 判断是否已空闲,如果在执行中,则直接return return; } canRun = false; setTimeout(function(){ console.log("函数节流"); canRun = true; }, 300); }; // 函数防抖 var

js 函数节流 jQuery throttle/debounce

在<JavaScript高级程序设计>一书有介绍函数节流,里面封装了这样一个函数节流函数: function throttle(method, context) { clearTimeout(methor.tId); method.tId = setTimeout(function(){ method.call(context); }, 100); } 它把定时器ID存为函数的一个属性.而调用的时候就直接写 window.onresize = function(){ throttle(myFu

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

问题1:如果实现了dom拖拽功能,但是在绑定拖拽事件的时候发现每当元素稍微移动一点便触发了大量的回调函数,导致浏览器直接卡死,这个时候怎么办? 问题2:如果给一个按钮绑定了表单提交的post事件,但是用户有些时候在网络情况极差的情况下多次点击按钮造成表单重复提交,如何防止多次提交的发生? 为了应对如上场景,便出现了 函数防抖 和 函数节流 两个概念,总的来说:这两个方法是在时间轴上控制函数的执行次数. 1.函数防抖(debounce) 概念: 在事件被触发n秒后再执行回调,如果在这n秒内又被触发

js 函数节流 与 防抖动

函数节流:就如同成都摇号买房,前一个进去选房了,下一个就要等一段时间.这种策略就很好的解决了,一大波人进去选房,销售妹妹没发接待的尴尬局面. 应用场景:监听浏览器滚动条,然后触发函数. // 普通做法 document.getElementById("throttle").onscroll = function(){ //监听到滚动就直接触发,不停滚动就不停触发 callback(); }; // 函数节流 var canRun = true; document.getElementB

js函数节流和函数防抖

概念解释 函数节流: 频繁触发,但只在特定的时间内才执行一次代码 函数防抖: 频繁触发,但只在特定的时间内没有触发执行条件才执行一次代码 函数节流 函数节流应用的实际场景,多数在监听页面元素滚动事件的时候会用到.因为滚动事件,是一个高频触发的事件. 以下是监听页面元素滚动的示例代码: // 函数节流var canRun = true; document.getElementById("throttle").onscroll = function(){ if(!canRun){ // 判

浅谈JS函数节流及应用场景

说完防抖,下面我们讲讲节流,规矩就不说了,先上代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no&