最近一个面试官问了我一个函数节流的问题,大概是:Js 方法传入两个参数:一个时间值、一个函数,返回一个函数。在这个时间间隔内,无论用户怎么触发这个函数,只执行一次这个函数,直到这个时间走完才可以执行第二次这个函数。然后感觉自己工作中遇到过这个问题,但是不知道这种形式就是函数节流。下面我来说下这个Js的高级问题,思路:函数节流就是防止用户高频调用某个事件而做的Js层面的处理方法。主要就是在一定时间内让用户的操作只执行一次指定方法。
代码实现(html):
<!doctype html> <html> <head> </head> <body> <button id="clickme" value="">点我,我不理你</button> </body> <script src="test.js"></script> </html>
代码实现(Js):
function ST(num , fun){ if(!ST.prototype.isopen){ ST.prototype.isopen = "ok"; setInterval(function(){ return ST.prototype.isopen = "ok"; },num); return fun; } if(ST.prototype.isopen == "ok"){ ST.prototype.isopen = "no"; return fun; } } document.getElementById("clickme").addEventListener('click',function(){ var myFun = ST(6000,function(){ return console.log("this :" +Math.random(10)); }) if(typeof myFun === "function") myFun(); });
当然啦,这个只是本人在没有参照的情况下自己的实现,其实社区中早就有人提出了这个最佳实践(可能需要FQ)
下面这个就是社区中的最佳实践:
var movers = document.querySelectorAll('.mover'), lastScrollY = 0, ticking = false; /** * Set everthing up and position all the DOM elements * - normally done with the CSS but, hey, there's heaps * of them so we're doing it here! */ (function init() { for(var m = 0; m < movers.length; m++) { movers[m].style.top = (m * 10) + 'px'; } })(); /** * Callback for our scroll event - just * keeps track of the last scroll value */ function onScroll() { lastScrollY = window.scrollY; requestTick(); } /** * Calls rAF if it's not already * been done already */ function requestTick() { if(!ticking) { requestAnimationFrame(update); ticking = true; } } /** * Our animation callback */ function update() { var mover = null, moverTop = [], halfWindowHeight = window.innerHeight * 0.5, offset = 0; // first loop is going to do all // the reflows (since we use offsetTop) for(var m = 0; m < movers.length; m++) { mover = movers[m]; moverTop[m] = mover.offsetTop; } // second loop is going to go through // the movers and add the left class // to the elements' classlist for(var m = 0; m < movers.length; m++) { mover = movers[m]; if(lastScrollY > moverTop[m] - halfWindowHeight) { mover.classList.add('left'); } else { mover.classList.remove('left'); } } // allow further rAFs to be called ticking = false; } // only listen for scroll events window.addEventListener('scroll', onScroll, false);
实现原理都是一样的,欢迎大家流言。