zoukankan      html  css  js  c++  java
  • 可视区渲染方案原理分析

    移动端页面随着滑动的dom越来越长,会出现卡顿的现象,进而降低用户体验,于是可视区渲染方案出来。

    可视区渲染就像一句话说的:敌不动我动,山不就我我就山。

    可视区渲染原理:

    1,有个滚动区域,下面的content类,要求overflow:auto,也就是可以使用滚动;在实际项目开发中这个根据可视区窗口大小变化

    2,一个足够高的渲染盒子,下面中viewArea类,其高度等于所有内容条数x单条内容高度,在实际项目中这个会受限于手机html的最大高度限制

    3,可视区显示的内容条数viewArea类里面的内容,内容多少可以通过pageSize控制

    4,通过监听滚动事件,触发可视区内容更新,包括更新呈现的内容以及更新内容的位置,后者其实是人为制造了一种滚动效果

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>无限滚动中的虚拟列表(只渲染可视区域,dom元素可复用)</title>
        <meta name="viewport" content="initial-scale=1.0">
        <meta name="format-detection" content="telephone=no, email=no">
    </head>
    
    <body>
        <header>
            <!-- <h1>无限滚动中的虚拟列表-防抖和节流(只渲染可视区域,dom元素可复用)</h1> -->
            <h1>无限滚动中的虚拟列表(只渲染可视区域,dom元素可复用)</h1>
        </header>
        </article>
        <article class="d-part d-effect">
            <style>
                .container {
                    height: 600px;
                    overflow: auto;
                }
    
                .item {
                    min-height: 60px;
                    border-bottom: 1px solid #cccccc;
                    border-top: 1px solid #cccccc;
                     100%;
                    text-align: center;
                    background-color: darkgray;
                    /* padding: 30px 0;
                    box-sizing: border-box; */
                }
            </style>
            <div class="container">
                <div class="content">
                    <div class="viewArea">
                        <div class="item">0</div>
                        <div class="item">1</div>
                        <div class="item">2</div>
                        <div class="item">3</div>
                        <div class="item">4</div>
                        <div class="item">5</div>
                        <div class="item">6</div>
                        <div class="item">7</div>
                        <div class="item">8</div>
                        <div class="item">9</div>
                    </div>
    
                </div>
            </div>
            <script>
                var item = document.querySelector('.viewArea .item');  //需要渲染的单个列表元素
                var container = document.querySelector('.container');  //可视区域元素盒子
    
                console.log(item);
                var start = 0; // 开始位置
                var pageSize = 10; // 每页展示的数据
                var total = 100000; //数据总长度
    
                // var itemHeight = 61; // 每个item的高度
                var itemStyle = getComputedStyle(item); // 获取元素最终样式
                var itemHeight = Number(itemStyle.height.split('px')[0]) + Number(itemStyle.borderTopWidth.split('px')[0]) + Number(itemStyle.borderBottomWidth.split('px')[0]); // 每个item的高度
                console.log('itemHeight', itemHeight);
    
    
                // 设置数据列表的总高度
                document.querySelector('.container .content').style.height = itemHeight * total + 'px';
                updateDom(start, pageSize, 0);
                
                //更新渲染列表的高度和数据
                function updateDom(start, pageSize, height) {
                    document.querySelector('.container .content .viewArea').style.transform = 'translateY(' + height + 'px)';
                    let all = document.querySelectorAll('.viewArea .item'); // 获取所有渲染列表
                    for (var i = start, itemIndex = 0, len = start + pageSize; i < len; i++, itemIndex++) {
                        all[itemIndex].innerHTML = i;
                    }
                }
                // 滚动处理函数
                function handleScroller() {
                    var lastStart = 0; // 上次开始的位置
                    return () => {
                        var currentScrollTop = container.scrollTop;
                        var fixedScrollTop = currentScrollTop - currentScrollTop % itemHeight;  // currentScrollTop % itemHeight这个是为了让滚动效果更自然
                        console.log(currentScrollTop, currentScrollTop % itemHeight)
                        var start = Math.floor(currentScrollTop / itemHeight);
                        if (lastStart !== start) {   // 这块避免一些重复性渲染,这样也不用计算方向了
                            lastStart = start;
                            updateDom(start, pageSize, fixedScrollTop);
                        }
                    }
                }
    
                document.querySelector('.container').addEventListener('scroll', handleScroller(), false);
            </script>
        </article>
        </div>
    </body>
    
    </html>
    我站在山顶看风景!下面是我的家乡!
  • 相关阅读:
    14_java之变量|参数|返回值|修饰符
    NYOJ 202 红黑树 (二叉树)
    NYOJ 138 找球号(二) (哈希)
    NYOJ 136 等式 (哈希)
    NYOJ 133 子序列 (离散化)
    NYOJ 129 树的判定 (并查集)
    NYOJ 117 求逆序数 (树状数组)
    NYOJ 93 汉诺塔 (数学)
    HDU 2050 折线分割平面 (数学)
    天梯赛L2-008 最长对称子串 (字符串处理)
  • 原文地址:https://www.cnblogs.com/zhensg123/p/14696409.html
Copyright © 2011-2022 走看看