• 虚拟滚动条实现大数据集预览


    <html>
    <head>
        <meta charset="UTF-8">
        <title>scroller</title>
        <style>
            .container {
                width: 500px;
                margin: 80px auto 0;
            }
            .wrapper {
                position:relative;
                width: 100%;
                height: 380px;
                overflow: hidden;
            }
            .view {
                position: absolute;
                width: 100%;
                height: 380px;
                border: 1px solid #678;
                overflow-y: scroll;
            }
            .buffer-view {
                position: absolute;
                top: 0;
                left: 0;
                width: 400px;
                background: #35a22e;
                overflow: hidden;
            }
            .actual-domain {
                height: auto;
            }
    
        </style>
    </head>
    <body>
        
        <div class="container">
            <div class="wrapper">
                <div class="buffer-view"></div>
                <div class="view">
                    <div class="actual-domain"></div>
                </div>
            </div>
        </div>
        <script src="z.js"></script>
        <script>
            var count = 1000000; // 数据长度
            var data = (function() {
                var len = count,arr = [];while (len--) arr[len] = { _rn: len, val: len+1 }; return arr;
            })();
    
            var PREBUFFER = 5;     // 预缓存10条记录
            var ROW_HEIGHT = 21;    // 每行元素高度:根据实际取值
            var PREBUFFER_HEIGHT = PREBUFFER * ROW_HEIGHT; // 前后预缓存元素高度
            var PREBUFFER_HEIGHT_TWICE = PREBUFFER_HEIGHT * 2;    // 前后预缓存之和高度
    
            var VIEW_HEIGHT = $('.view').height();    // 可视区视图高度
            var bufferView = $('.buffer-view').height($.nearestModulo(VIEW_HEIGHT, ROW_HEIGHT) +  PREBUFFER_HEIGHT*2);
    
            var ACTUALDOMAIN_HEIGHT = data.length * ROW_HEIGHT;    // 实际计算区域高度
            var size = bufferView.height() / ROW_HEIGHT;
            $('.actual-domain').height(ACTUALDOMAIN_HEIGHT);
            $('.view').on('scroll', function(evt) {
                var offset = $(this).offset();
                var bottom = ACTUALDOMAIN_HEIGHT - offset.top - VIEW_HEIGHT;
                var top = 0;
                
                if (offset.top < PREBUFFER_HEIGHT) {
                    top = -offset.top;
                } else if (bottom < PREBUFFER_HEIGHT) {
                    top    = bottom - PREBUFFER_HEIGHT_TWICE;        
                } else {
                    top = -PREBUFFER_HEIGHT;
                }
    
                bufferView.css({ top: top });
    
                var domain = range(offset.top, offset.top + VIEW_HEIGHT+PREBUFFER_HEIGHT_TWICE);
    
                if (offset.top + PREBUFFER_HEIGHT_TWICE + VIEW_HEIGHT <= ACTUALDOMAIN_HEIGHT) {
                    bufferView.setData(data.slice(domain[0], domain[1]));
                } else {
                    bufferView.setData(data.slice(-size));
                }
            });
    
            function range(start, end) {
                return [
                    $.nearestModulo(start, ROW_HEIGHT) /ROW_HEIGHT,
                    $.nearestModulo(end, ROW_HEIGHT) /ROW_HEIGHT
                ];
            }
    
            bufferView.append('li', size);
            bufferView.setData(data.slice(0, size));
    
        </script>
    </body>
    </html>

    需要引的js文件:z.js

    function $(selector) {
        return {
            dom: dom(selector),
            on: on,
            offset: offset,
            height: height,
            text: text,
            css: css,
            append: append,
            setData: setData,
            value: value
        };
    }
    $.log = function() {
        console.log.apply(console, arguments);
    };
    
    $.nearestModulo = function(num, module) {
        var val = num % module;
        if (val === 0) {
            return num;
        }
        
        return val < module/2 ? num - val : num + (module - val);
    }
    
    function dom(selector) {
        return typeof selector === 'object' 
        ? selector
        : document.querySelector(selector);
    }
    
    function on(evtName, handler, bobble) {
        addEventListener.call(this.dom, evtName, handler, !!bobble);
    }
    
    function offset() {
        return {
            left: this.dom.scrollLeft,
            top: this.dom.scrollTop
        };
    }
    
    function height(val) {
        if (isNaN(val)) {
            return this.dom.clientHeight;
        } else {
            this.dom.style.height = val;
            return this;
        }
    }
    
    function text(str) {
        this.dom.innerText = str;
        return this;
    }
    
    function css(attrs) {
        for (var attr in attrs) {
            if (attrs.hasOwnProperty(attr)) {
                this.dom.style[attr] = attrs[attr] + 'px';
            }
        }
    }
    
    function append(tagName, size) {
        var docFrag = document.createDocumentFragment();
        while (size--) {
            docFrag.appendChild(document.createElement(tagName));
        }
    
        this.dom.appendChild(docFrag);
    }
    
    function setData(data) {
        var childs = this.dom.childNodes;
    
        childs.forEach(function(node, i) {
            node.innerText = data[i].val;
        });
    }
    
    function value() {
        return this.dom.value;
    }
  • 相关阅读:
    分布式算法(一致性Hash算法)
    浅析Postgres中的并发控制(Concurrency Control)与事务特性(上)
    PostgreSQL内核分析——BTree索引
    源码安装postgresql数据库
    QEMU漏洞挖掘
    mysql远程连接数据库
    C++学习之路(十一):C++的初始化列表
    搭建本地git服务器
    C++面试常见问题
    SkipList 跳表
  • 原文地址:https://www.cnblogs.com/zhoulingfeng/p/7102992.html
Copyright © 2020-2023  润新知