js中两种计时器、防抖、节流

计时器

  • setTimeout():一次性计时器;
  • setInterval():连续计时器;
    用法
    两者除了一次性和连续,其他基本完全一样。
    1.两个参数

一般情况下计时器都是两个参数
格式: setTimeout(f,time)=>f为计时到达后需要执行的函数,time为计时器的时间。
举例:setTimeout(function(){console.log(1)},1000)//=>一秒后输出1
同时:setTimeout(f)// 等同于setTimeout(f, 0)
但是有时也会有多个参数:
setTimeout(function(a,b){console.log(a+b)},1000,1,2)//=>1,2分别为a,b的实参

** 需要注意的是:如果回掉函数是对象的时候,其中的this会指向全局对象

var a="3"
var obj={
   a:1,
   b:function(){console.log(this.a)}
}
setTimeout(obj.b,1000) //=>输出“3” this指向window对象

var str="全局";
var obj={
  str:"对象",
  func:function(){
    //var done=this.test     setTimeout(done,1000);
    setTimeout(this.test,1000);
  },
  test:function(){
    console.log(this.str);//=>"全局"
  }
}
obj.func()

解决作用域的办法:
1.使用bind、call、apply来绑定thissetTimeout(obj.b.bind/call/apply(obj),1000)
2.将obj.b放在函数中执行setTimeout(function(){obj.b()},1000)

使用计时器可以有效防止抖动事件,扯到防抖动,势必会扯出节流,接下来就谈谈这两个默认的小妖精。
使用setTimeout实现一个setInteval

function timer(){
    var time=setTimeout(function(){
        document.write(2)
        timer();
        clearTimeout(time)
    },1000)
}
timer()

防止抖动

  • 函数防抖是指对于在事件被触发n秒后再执行的回调,如果在这n秒内又重新被触发,则重新开始计时。
  • 思路:利用计时器setTimeout和clearTimeout,只要触发事件,就会销毁上一次的计时器,重新计时,计时结束后才会触发回掉函数的事件。
  • 适用于:
    表单组件输入内容验证;
    防止多次点击导致表单多次提交等情况;
    防止函数过于频繁的不必要的调用。

比如一个提交按钮,用户多次点击,然后计时器就会不断被销毁又重新创建,直到用户停止点击并且时长达到计时器时间,然后再执行提交事件。

html:
<button id="btn">提交</button>

js:
function debounce(fn) {
      let timeout = null; // 创建一个标记用来存放定时器的返回值
      return function () {
        clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉
        timeout = setTimeout(() => { // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行 fn 函数
          fn.apply(this, arguments);
        }, 3000);
      };
    }
    function sayHi() {
      console.log('防抖成功');
    }

    var btn = document.getElementById('btn');
    btn.addEventListener('click', debounce(sayHi));
    

节流

  • 节流的核心思想:不然该触发事件执行的太过频繁,通过定时器保证一段时间内只能执行一次。
  • 适用于:
    搜索框智能提示(每打一个字都有相应的智能检索,但是只在这个字打完为止才有效);
    检测鼠标的坐标(mousemove);
function scrollFn(){
    console.log(1)
}
function throttle(method,delay,duration){
    var timer=null;
    var begin=new Date();    
    return function(){                
        var context=this, args=arguments;
        var current=new Date();        
        clearTimeout(timer);
        if(current-begin>=duration){
            method.apply(context,args);
            begin=current;
        }else{
            timer=setTimeout(function(){
                method.apply(context,args);
            },delay);
        }
    }
}
window.onmousemove=throttle(scrollFn,100,500);
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值