看了下园友的一帖子:http://www.cnblogs.com/xzhang/p/4145697.html#commentform
本来以为是很简单的问题,但仔细想想还挺有意思的。简单的说就是增加事件触发的间隔时间。
比如在浏览器状态了事件是1毫秒调用一次,转换成100毫秒调用一次。
看了下原贴的两方法,觉得可以乐观锁的方法再写个,结果对比后发觉和typeahead差不多。贴下代码和测试页面。看那位能指点下写的更好。:)
var _lazyRun = function (func, wait) { var _preIndex = 0, _nowIndex = 1, _timer, _fnCur, _context, _result; var _fn1 = function () { if (_preIndex < _nowIndex) { _fnCur = _fn2; clearTimeout(_timer); var _previous = new Date(); _preIndex = _nowIndex; _result = func.apply(_context, _args); var _remaining = wait - ((new Date()) - _previous); if (_remaining < 0) { _result = func.apply(_context, _args); } else { _timer = setTimeout(_fn1, _remaining);//脱离线程 } } else { _fnCur = _fn1; _preIndex = 0, _nowIndex = 1; } return _result; }; var _fn2 = function () { _nowIndex++; return _result; }; _fnCur = _fn1; return function () { _context = this; _args = arguments; _result = _fnCur.apply(_context, _args); return _result; }; };
测试页面
<html> <head> <title> “如何稀释scroll事件”引出的问题 </title> <meta charset="utf-8"> <style type="text/css"> #box { border: 2px solid #f60; margin: 0 auto; } </style> </head> <body> <input id="waitTime" type="text" value="100" onchange="onscrollTest()" /> <select id="sel" onchange="onscrollTest()"> <option value="1">使用_lazyRun</option> <option value="2">使用debounce</option> <option value="3">使用throttle </option> </select> <div id="outDiv"></div> <div id="box" style="width:600px; height:6000px"> </div> </body> </html> <script type="text/javascript"> var _lazyRun = function (func, wait) { var _preIndex = 0, _nowIndex = 1, _timer, _fnCur, _context, _result; var _fn1 = function () { if (_preIndex < _nowIndex) { _fnCur = _fn2; clearTimeout(_timer); var _previous = new Date(); _preIndex = _nowIndex; _result = func.apply(_context, _args); var _remaining = wait - ((new Date()) - _previous); if (_remaining < 0) { _result = func.apply(_context, _args); } else { _timer = setTimeout(_fn1, _remaining);//脱离线程 } } else { _fnCur = _fn1; _preIndex = 0, _nowIndex = 1; } return _result; }; var _fn2 = function () { _nowIndex++; return _result; }; _fnCur = _fn1; return function () { _context = this; _args = arguments; _result = _fnCur.apply(_context, _args); return _result; }; }; //**************************underscore.js 的 debounce /** * [debounce description] * @param {[type]} func [回调函数] * @param {[type]} wait [等待时长] * @param {[type]} immediate [是否立即执行] * @return {[type]} [description] */ var _ = {}; _.debounce = function (func, wait, immediate) { var timeout, args, context, timestamp, result; var later = function () { var last = _.now() - timestamp; //小于wait时间,继续延迟wait-last执行later,知道last >= wait才执行func if (last < wait && last > 0) { timeout = setTimeout(later, wait - last); } else { timeout = null; if (!immediate) { result = func.apply(context, args); if (!timeout) context = args = null; } } }; return function () { context = this; args = arguments; timestamp = _.now(); //是否立即执行 var callNow = immediate && !timeout; if (!timeout) timeout = setTimeout(later, wait); if (callNow) { result = func.apply(context, args); context = args = null; } return result; }; }; _.now = Date.now || function () { return new Date().getTime(); }; //**************************typeahead.js 的 throttle var throttle = function (func, wait) { var context, args, timeout, result, previous, later; previous = 0; later = function () { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function () { var now = new Date(), remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { //如果大于间隔时间(wait) clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { //小于,延时调用later timeout = setTimeout(later, remaining); } return result; }; }; //**************************测试*********************************** var _testCount = 0; var _test = function () { console.log(_.now()) _testCount++; //console.log(window.scrollY || document.documentElement.scrollTop); }; function onscrollTest() { _testCount = 0; var _waitTime = document.getElementById("waitTime").value; switch (document.getElementById("sel").value) { case "1"://_lazyRun document.getElementById("outDiv").innerText = "use _lazyRun function ,wait time is " + _waitTime; window.onscroll = _lazyRun(_test, _waitTime); break; case "2"://debounce document.getElementById("outDiv").innerText = "use debounce function ,wait time is " + _waitTime; window.onscroll = _.debounce(_test, _waitTime); break; case "3"://throttle document.getElementById("outDiv").innerText = "use throttle function ,wait time is " + _waitTime; window.onscroll = throttle(_test, _waitTime); break; }; console.clear(); } onscrollTest(); </script>
时间: 2024-10-13 14:42:55