定时器、防抖、节流的练习

一、定时器的练习

setInterval:定时调用
可以将一个函数,每隔一段时间执行一次;
参数1:回调函数,该函数会每隔一段时间被调用一次;
参数2:每次调用间隔的时间,单位:毫秒
返回值:返回一个Number类型的数据,这个数据用来作为定时器的唯一标识;

 var num = 1;
 var timer = setInterval(function() {
    count.innerHTML = num++
    if(num == 21) {
      clearInterval(timer)
    }
 }, 200)

切换图片的练习:

var img = document.getElementsByTagName('img')[0]
var arr = ['./1.jpg', './2.jpg', './3.jpg', 
'./4.jpg', './5.jpg']
var i = 0;
setInterval(function() {
  i++;
  if (i >= arr.length) {i = 0} // 或者使用下面一行的写法
  i = i % arr.length
  img.src = arr[i]
}, 500)

如果设置一个按钮,点击按钮,执行定时器;会有一个问题,如果连续点击按钮,则会开启很多个定时器,所以切换速度会越来越快,而且timer是赋值给最新的定时器,所以关闭定时器只能关闭最后一个定时器(导致无法关闭所有的定时器)

解决办法:开启一个定时器时,先关闭上一个定时器

定时器的应用:

<div><button id="btn">点击图片,进行移动</button></div>
<div id="box"></div>

function getStyle(obj, name) {
  return getComputedStyle(obj, null)[name]
}
var box = document.getElementById("box")
var btn = document.getElementById("btn")
var timer;
btn.onclick = function() {
  clearInterval(timer)
  timer = setInterval(() => {
    var oldValue = parseInt(getStyle(box, 'left'))
    var newValue = oldValue + 4
    if (newValue >= 600) {
      newValue = 600
    }
    box.style.left = newValue + "px"
    if (newValue == 600) {
      clearInterval(timer)
    }
  }, 30); 
}

二、延时调用

定时调用会执行多次,而延时调用只会执行一次

var num = 0;
// 隔一段时间再执行,而且只会执行一次
var timer = setTimeout(function() {
  console.log(++num) // 先自增,后执行num表达式,打印1
  console.log(num++) // 先执行num表达式,后自增,打印0
}, 1000)

// 关闭延时调用
clearTimeout(timer)

三、防抖

事件被触发n秒后再执行回调函数,如果在这n秒内又被触发,则重新计时;应用场景:

  1. 用户在输入框中连续输入一串字符后,只会在输入完后去执行最后一次的查询ajax请求,这样可以有效减少请求次数,节约请求资源;
  2. window的resize、scroll事件,不断地调整浏览器的窗口大小,或者滚动时会触发对应事件,防抖让其只触发一次;
  3. 搜索框搜索输入,手机号、邮箱验证输入
<body>
<div>
  <input type="text">
  <input type="submit" id="input">
</div>
<script type="text/javascript">
const btn = document.getElementById("input")
btn.addEventListener("click", debounce(submit), false)

function debounce(fn, timer) {
  let t = null
  return function() {
    let firstClick = !t
    if (t) { clearTimeout(t) }
    if(firstClick) { fn() }
    t = setTimeout(() => {
      t = null
    }, timer)
  }
}

function submit() {
  console.log(1)
}
</script>
</body>

Vue中的防抖

<template>
	<div id="app">
		<input type="text" placeholder="请输入手机号码" 
	       v-model="val" @keyup="check"/>
	    <div class="box" v-show="statu==true">
	    您输入的手机号码格式正确</div>
	</div>
</template>

<script>
import {debouce} from 'common/utils'
export default {
   methods: {
    // check是我们绑定的输入框的@keyup事件,注意这里不能是函数,
    // 不然不会触发,必须要是对象
      check: debounce(function(){
           this.handle()
           }),
      handle() {
            let reg = /^1[3|4|5|7|8][0-9]{9}$/;    
            if(reg.test(this.val)){
                 this.statu=true;
            }
       }
  
   	}
}
</script>

 export function debounce(fn, delay = 100) {   //默认100毫秒
    let timer;
    return function() {
        if(timer) { clearTimeout(timer) }
        timer = setTimeout(() => {
		// 定时器必须要更改this指向,可以用apply、bind、
		// 或者上面用变量转换等方式来进行更改this指向
        	fn.apply(this);   // this 指向vue
        }, delay);
    };
}

四、节流

规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只能有一次能生效。(一个函数可以在短时间内被调用的次数);应用场景:

  1. 鼠标连续不断地触发某事件(如点击),在单位时间内只触发一次;
  2. 在页面的无限加载场景下,需要用户在滚动页面时,每隔一段时间发一次ajax请求,而不是在用户听下滚动页面操作时,才去请求数据;
  3. 监听滚动时间,比如是否滑到底自动加载更多
const btn = document.getElementById("input")
btn.addEventListener("click", throttle(submit, 1000), false)
function throttle(fn, delay) {
  let begin = 0
  return function() {
    let cur = new Date().getTime()
    if (cur - begin > delay) {
      fn(arguments)
      begin = cur
    }
  }
}

function submit(e) {
  console.log(e)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值