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>
    我站在山顶看风景!下面是我的家乡!
  • 相关阅读:
    Android Wear真机蓝牙调试方法及错误解决方法,设备华为WATCH+小米5
    Ubuntu16.04 Selenium+python 环境搭建 Chromedriver安装
    Ubuntu16.04 为vim安装YouCompleteMe插件
    codeforces 676C Vasya and String 贪心 尺取法
    poj 1177 & hdu 1828 Picture 线段树 扫描线求矩形周长并
    hdu 1542 & poj 1151 Atlantis 线段树扫描线求矩形面积并
    fzu 2109 Mountain Number 数位DP
    fzu 2105 Digits Count 线段树
    codeforces 675D Tree Construction 数据结构
    codeforces 675C Money Transfers 贪心
  • 原文地址:https://www.cnblogs.com/zhensg123/p/14696409.html
Copyright © 2011-2022 走看看