/*
* 防抖函数
* 在规定的时间内,频繁的操作执行函数(例如用户点击多次按钮),只执行第一次或者最后一次(防止函数在没执行完的情况下,多次被触发)
* 参数 func 执行函数
* wait 规定的之间内
* immediate 判断执行第一次或最后一次
*/
let fnDebounce = function fnDebounce(func,wait,immediate){
// 判断传入值的变量问题 start
if(typeof func !== 'function') throw new TypeError('func must be a function')
if(typeof wait === 'undefined'){
wait = 500;
immediate = false;
}
if(typeof wait === 'boolean'){
wait = 500;
immediate = wait;
}
if(typeof wait !== 'number')throw new TypeError('wait must be a number')
if(typeof immediate !== 'boolean')throw new TypeError('immediate must be a boolean')
// 判断传入值的变量问题 over
var timer = null,result;
return function proxy () {
var self =this, params=[].slice.call(arguments),
callNow = !timer && immediate;
if(timer) clearTimeout(timer);
timer = setTimeout(function(){
clearTimeout(timer);
timer = null;
if(!immediate) result = func.apply(self,params);
},wait)
if(callNow) result = func.apply(self,params);
return result;
}
}
js中使用
<div id="app">
<button id="submit" onclick="fnTest()">防抖测试</button>
</div>
<script src="./untis.js"></script>
<script>
let fnButton = function fnButton(){
console.log('执行函数')
}
let submit = document.getElementById('submit');
// submit.onclick = fnDebounce(fnButton,500,true);
// submit.addEventListener('click',fnDebounce(fnButton,500,true))
fnTest = fnDebounce( fnButton, 500, true);
</script>
vue中使用
<template>
<div id="app">
<!-- 防抖测试 -->
<button @click="fnTest">防抖测试</button>
</div>
</template>
<script>
import utils from './units/index';
export default {
methods:{
fnTest(){
this.fnButton();
},
fnButton: utils.fnDebounce(function() { console.log('执行函数')
},500),
}
}
</script>
react中使用
import React from 'react';
import { withRouter } from 'react-router-dom';
import { connect } from "react-redux";
import { Button, Form } from 'antd';
const FormItem = Form.Item;
import units from './units.js';
class test extends React.Component {
fnTest = units.fnDebounce(function(){
console.log('执行函数')
},500,true)
render() {
return (
<div className="content_library flex" >
<Button onClick={this.fnTest.bind(this)} >防抖测试</Button>
</div>
)
}
}
test = Form.create()(test);
function select(state) { return { };}
export default withRouter(connect(select)(test));
节流(使用方法同防抖)
/*
* 节流函数
* 在频繁的操作情况下,每隔指定的时间段,去执行函数
* 参数 func 执行函数
* wait 规定的之间内
*/
function fnThrottle(func, wait){
if(typeof func !== 'function') throw new TypeError('func must be a function')
// wait 转为数字
wait = +wait;
// 不是时间,默认给 300
if (isNaN(wait)) wait = 300;
var timer = null,
previous = 0,
result;
return function proxy() {
var self = this,
params = [].slice.call(arguments);
var now = +new Date,
// 剩下等待执行的时间
remaining = wait - (now - previous);
if(remaining <= 0) {
// 两次间隔时间已经超过WAIT了,此时我们立即执行
previous = now;
result = func.apply(self, params);
return result;
}
// 没有定时器我们才设置,有定时器说明上次还没执行呢,只有上次执行了,我们才开启下一次
if(!timer) {
timer = setTimeout(function(){
clearTimeout(timer);
timer = null;
previous = +new Date;
result = func.apply(self, params);
},remaining);
}
return result;
}
}