码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2014-12-06 01:24:28      阅读:245      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   io   ar   使用   sp   for   

看了下园友的一帖子: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>

  

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

标签:des   style   blog   http   io   ar   使用   sp   for   

原文地址:http://www.cnblogs.com/Grart/p/4147716.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!