virtual-scroller(上)

<html>
<head>
    <meta charset="UTF-8">
    <title>test</title>

    <style type="text/css">
        .viewpoint {
            margin: 20px auto;
            width: 380px;
            height: 200px;
            border: 1px solid #333;
            overflow-y:scroll;
        }
        .canvas {
            height: 20000px;
        }
    </style>
</head>
<body>
    <div class="viewpoint">
        <div class="canvas"></div>
    </div>
    <div class="log"></div>
    <script>
        var lineHeight = 10;
        var data = new Array(2000).fill(0).map((d, i) => ({ v: i }));
        var buffer = {
            start: 0,
            limit: 200/ 10,
            domain:[0, 20],
            isAmong(value) {
                return buffer.domain[0] <= value && value <= buffer.domain[1];
            },
            preLoad(dir, index) {
                if (dir === 0) return false;

                var current = ~~(index/ lineHeight), [start, end] = buffer.domain;

                // scroll up
                if (dir < 0 && current < Math.max(0, start + buffer.limit)) {
                    end = buffer.isAmong(current) ? start - 1 : current;
                    start = end - buffer.limit;

                    buffer.domain = [start, end];
                    return true;
                } 

                // scroll down
                if (dir > 0 && current > end - buffer.limit) {
                    start = buffer.isAmong(current) ? end + 1 : current;
                    end = start + buffer.limit;

                    buffer.domain = [start, end];
                    return true;
                }
                
                return false;
            }
        };
        var scroller = { 
            dir: 0, // -1,0,-1
            preIndex: 0,
            on(fn) {
                this.fn = function(index) {
                    log('current', index);
                    scroller.dir = index - scroller.preIndex;
                    if (buffer.preLoad(scroller.dir, scroller.preIndex = index)) {
                        fn(scroller.dir > 0 ? 1 : -1, buffer.domain, index);
                    }
                };
            }, 
            fire() {this.fn.apply(this, arguments);} 
        };

        var dataView = {
            getRange(start, end) {
                return data.slice(start, end);
            }
        };
        

        document.querySelector('.viewpoint').addEventListener('scroll', function(evt) {
            // console.log(this.scrollTop);
            scroller.fire(this.scrollTop);
        });

        scroller.on(function(dir, [start, limit], offsetTop) {
            console.log(dir, start, limit, offsetTop);
            // console.log(dataView.getRange(start, limit));
        });


        var $log = document.querySelector('.log');
        function log(...args) {
            $log.innerHTML = args;
        }
    </script>
</body>
</html>

 

posted @ 2017-07-27 22:49  风之约  阅读(662)  评论(0编辑  收藏  举报