长列表优化之滚动替换数据方案小记

简介:

  最近项目中要用到比较长的列表,在浏览器中打开渲染时比较慢,并占用了较多内存,于是就同事就建议尽量减少节点,在滚动时只是替换数据,于是就决定试试这种方法。

  首先要做的就是添加拖动滚动条时的事件,另外由于UE要求对滚动条进行美化,于是就选用了jscrollpane这个jQuery滚动条插件,主页是:http://jscrollpane.kelvinluck.com/

  基本要求是表头固定,内容可滚动,滚动时只是替换数据,不增减节点。由于要出现滚动条,所以要添加一个空的节点来占位,所以DEMO的HTML结构如下:

<h3>DEMO</h3>
<div class="bookList">
    <table class="bookList_head">
        <thead>
            <tr>
                <th class="book_title">Title</th>
                <th class="book_time">Time</th>
                <th class="book_author">Author</th>
                <th class="book_prize">Prize</th>
            </tr>
        </thead>
    </table>
    <div class="scroll-pane">
        <div id="emptyContainer" class="emptyContainer"></div>
        <table class="bookList_body">
            <tbody id="bookContent">
            </tbody>
        </table>
    </div>
</div>

  然后要做的就是用测试数据填充列表,并给占位节点设置高度,JS代码如下:

    var bookData = [],
        bookMap = [],
        bookCount = 1000,
        showCount = 10,
        bookListBodyNode = $(".bookList_body"),
        bookContentNode = $("#bookContent"),
        itemHeight = 0,
        oFragment = document.createDocumentFragment();

    var emptyContainerNode = $("#emptyContainer");
    for(var i=0;i<bookCount;i++){
        bookData.push({
            "title":"JavaScript高级程序设计第"+(i+1)+"版",
            "time":"2013-1-27",
            "author":"佚名"+i,
            "prize":(i%50+1)+".00"
        });
    }
    
    for(i=0;i<showCount;i++){
        var bookItem = $("<tr></tr>"),
            bookItem_title = $("<td class=\"book_title\">" + bookData[i].title + "</td>"),
            bookItem_time = $("<td class=\"book_time\">" + bookData[i].time + "</td>"),
            bookItem_author = $("<td class=\"book_author\">" + bookData[i].author + "</td>"),
            bookItem_prize = $("<td class=\"book_prize\">" + bookData[i].prize + "</td>");
        bookItem.append(bookItem_title)
            .append(bookItem_time)
            .append(bookItem_author)
            .append(bookItem_prize);
        bookMap[i] = bookItem;
        oFragment.appendChild(bookItem[0]);
    }
    bookContentNode[0].appendChild(oFragment);
    itemHeight = parseInt(bookMap[0].height());
    emptyContainerNode.css("height", bookCount * itemHeight);

  下一步就是给class为scroll-pane的节点应用jScrollPane插件添加滚动条,同是要添加滚动条滚动时的事件,代码如下:

$('.scroll-pane').bind('jsp-scroll-y',function(event, scrollPositionY, isAtTop, isAtBottom){
        bookListBodyNode.css("top",scrollPositionY);
        replaceBooklistData(scrollPositionY);
    }
).jScrollPane();

function replaceBooklistData(scrollPositionY){
    var beginIndex = Math.round(scrollPositionY / itemHeight);
    for(var i=0;i<showCount;i++){
        var bookItem = bookMap[i],
            bookItem_title = bookItem.find(".book_title"),
            bookItem_time = bookItem.find(".book_time"),
            bookItem_author = bookItem.find(".book_author"),
            bookItem_prize = bookItem.find(".book_prize");
        bookItem_title.html(bookData[i+beginIndex].title);
        bookItem_time.html(bookData[i+beginIndex].time);
        bookItem_author.html(bookData[i+beginIndex].author);
        bookItem_prize.html(bookData[i+beginIndex].prize);
    }
}

  最后还要引入一个鼠标滚动时的插件mousewheel,全部代码如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Table Body Scroll Demo</title>
        <link type="text/css" href="style/jquery.jscrollpane.css" rel="stylesheet" media="all" />
        <link type="text/css" href="style/demo.css" rel="stylesheet" media="all" />
        <script type="text/javascript" src="script/jquery.js"></script>
        <script type="text/javascript" src="script/jquery.mousewheel.js"></script>
        <script type="text/javascript" src="script/jquery.jscrollpane.min.js"></script>
    </head>
    <body>
        <h3>DEMO</h3>
        <div class="bookList">
            <table class="bookList_head">
                <thead>
                    <tr>
                        <th class="book_title">Title</th>
                        <th class="book_time">Time</th>
                        <th class="book_author">Author</th>
                        <th class="book_prize">Prize</th>
                    </tr>
                </thead>
            </table>
            <div class="scroll-pane">
                <div id="emptyContainer" class="emptyContainer"></div>
                <table class="bookList_body">
                    <tbody id="bookContent">
                    </tbody>
                </table>
            </div>
        </div>
        <script type="text/javascript" id="sourcecode">
            var bookData = [],
                bookMap = [],
                bookCount = 1000,
                showCount = 10,
                bookListBodyNode = $(".bookList_body"),
                bookContentNode = $("#bookContent"),
                itemHeight = 0,
                oFragment = document.createDocumentFragment();
                
            $(function(){
                $('.scroll-pane').bind('jsp-scroll-y',
                    function(event, scrollPositionY, isAtTop, isAtBottom){
                        bookListBodyNode.css("top",scrollPositionY);
                        replaceBooklistData(scrollPositionY);
                    }
                ).jScrollPane();
            });

            loadData();

            function replaceBooklistData(scrollPositionY){
                var beginIndex = Math.round(scrollPositionY / itemHeight);
                for(var i=0;i<showCount;i++){
                    var bookItem = bookMap[i],
                        bookItem_title = bookItem.find(".book_title"),
                        bookItem_time = bookItem.find(".book_time"),
                        bookItem_author = bookItem.find(".book_author"),
                        bookItem_prize = bookItem.find(".book_prize");
                    bookItem_title.html(bookData[i+beginIndex].title);
                    bookItem_time.html(bookData[i+beginIndex].time);
                    bookItem_author.html(bookData[i+beginIndex].author);
                    bookItem_prize.html(bookData[i+beginIndex].prize);
                }
            }

            function loadData(){
                var    emptyContainerNode = $("#emptyContainer");
                for(var i=0;i<bookCount;i++){
                    bookData.push({
                        "title":"JavaScript高级程序设计第"+(i+1)+"",
                        "time":"2013-1-27",
                        "author":"佚名"+i,
                        "prize":(i%50+1)+".00"
                    });
                }
                
                for(i=0;i<showCount;i++){
                    var bookItem = $("<tr></tr>"),
                        bookItem_title = $("<td class=\"book_title\">" + bookData[i].title + "</td>"),
                        bookItem_time = $("<td class=\"book_time\">" + bookData[i].time + "</td>"),
                        bookItem_author = $("<td class=\"book_author\">" + bookData[i].author + "</td>"),
                        bookItem_prize = $("<td class=\"book_prize\">" + bookData[i].prize + "</td>");
                    bookItem.append(bookItem_title)
                        .append(bookItem_time)
                        .append(bookItem_author)
                        .append(bookItem_prize);
                    bookMap[i] = bookItem;
                    oFragment.appendChild(bookItem[0]);
                }
                bookContentNode[0].appendChild(oFragment);
                itemHeight = parseInt(bookMap[0].height()) || 34;//FOR IE7
                emptyContainerNode.css("height", bookCount * itemHeight);
            }
        </script>
    </body>
</html>

  代码中的CSS(除了demo.css)和JS都可以在这里找到:https://github.com/vitch/jScrollPane

   demo.css代码如下:

.bookList{
    width:520px;
    height:364px;
}
.scroll-pane
{
    height:330px;
    overflow: auto;
}
.bookList .bookList_head,.bookList .bookList_body{
    width:100%;
    border-collapse:collapse;
}
.bookList .bookList_body{
    z-index:999;
    position:absolute;
    top:0;
    left:0;
}
.bookList .bookList_head thead{
    background-color:#F2F4F6;
}
.bookList th,.bookList td{
    padding:8px 0px 8px 5px;
    text-align:left;
    border-bottom:1px solid #CCC;
    font-size:14px;
}
.bookList .bookList_body tr:nth-child(even){
    background-color:#F0F0F0;
}
.bookList .bookList_body tr:hover{
    background-color:#CCC;
}
.book_title{
    width:250px;
}
.book_time{
    width:100px;
}
.book_author{
    width:80px;
}
.book_prize{
} 
.emptyContainer{
    width:100%;
    z-index:-1;
}

  初步测试,在IE6/7/8/9、chrome、firefox下均正常显示,如果大家有更好方案,欢迎分享。



本文转自Artwl博客园博客,原文链接:http://www.cnblogs.com/artwl/,如需转载请自行联系原作者

相关文章
|
Linux Windows
Centos 7镜像利用命令行安装GNOME、KDE图形界面
Centos 7镜像利用命令行安装GNOME、KDE图形界面
Centos 7镜像利用命令行安装GNOME、KDE图形界面
|
Java 大数据 Spring
带你了解什么是Spring Ioc
你好看官,里面请!今天笔者讲的是Spring Ioc。不懂或者觉得我写的有问题可以在评论区留言,我看到会及时回复。 注意:本文仅用于学习参考,不可用于商业用途,如需转载请跟我联系。
327 1
|
SQL 分布式计算 算法
双非数学硕士零基础转大数据开发,收割腾讯 字节 百度等10个大厂 SP offer
双非数学硕士零基础转大数据开发,收割腾讯 字节 百度等10个大厂 SP offer
双非数学硕士零基础转大数据开发,收割腾讯 字节 百度等10个大厂 SP offer
|
架构师 Java 物联网
阿里云ACE成长记:从外包到世界500强,再进阶为系统架构师之路
当我和席斐通话后得知他同样有从外包转为惠普正式员工的工作经历后,心中便已确定这是一位在技术上有故事的人。
|
4天前
|
云安全 人工智能 自然语言处理
|
8天前
|
人工智能 Java API
Java 正式进入 Agentic AI 时代:Spring AI Alibaba 1.1 发布背后的技术演进
Spring AI Alibaba 1.1 正式发布,提供极简方式构建企业级AI智能体。基于ReactAgent核心,支持多智能体协作、上下文工程与生产级管控,助力开发者快速打造可靠、可扩展的智能应用。
800 17
|
11天前
|
数据采集 人工智能 自然语言处理
Meta SAM3开源:让图像分割,听懂你的话
Meta发布并开源SAM 3,首个支持文本或视觉提示的统一图像视频分割模型,可精准分割“红色条纹伞”等开放词汇概念,覆盖400万独特概念,性能达人类水平75%–80%,推动视觉分割新突破。
805 59
Meta SAM3开源:让图像分割,听懂你的话
|
2天前
|
人工智能 安全 小程序
阿里云无影云电脑是什么?最新收费价格个人版、企业版和商业版无影云电脑收费价格
阿里云无影云电脑是运行在云端的虚拟电脑,分企业版和个人版。企业版适用于办公、设计等场景,4核8G配置低至199元/年;个人版适合游戏、娱乐,黄金款14元/月起。支持多端接入,灵活按需使用。
236 164