首页 > 代码库 > “如何稀释scroll事件”的思考

“如何稀释scroll事件”的思考

看了下园友的一帖子: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="http://www.mamicode.com/100" onchange="onscrollTest()" />    <select id="sel" onchange="onscrollTest()">        <option value="http://www.mamicode.com/1">使用_lazyRun</option>        <option value="http://www.mamicode.com/2">使用debounce</option>        <option value="http://www.mamicode.com/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>

  

“如何稀释scroll事件”的思考