zoukankan      html  css  js  c++  java
  • 长列表优化之滚动替换数据方案小记

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

      首先要做的就是添加拖动滚动条时的事件,另外由于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://artwl.cnblogs.com

    本文首发博客园,版权归作者跟博客园共有。转载必须保留本段声明,并在页面显著位置给出本文链接,否则保留追究法律责任的权利。

  • 相关阅读:
    Chrome 中的彩蛋,一款小游戏,你知道吗?
    Json对象与Json字符串互转(4种转换方式)
    [PHP自动化-进阶]005.Snoopy采集框架介绍
    [PHP自动化-进阶]004.Snoopy VS CURL 模拟Discuz.net登陆
    [PHP自动化-进阶]003.CURL处理Https请求访问
    [PHP自动化-进阶]002.CURL模拟登录带有验证码的网站
    [PHP自动化-进阶]001.CURL模拟登录并采集数据
    [注]2015中国程序员生存报告,你苦你先看@^@
    [JavaWeb基础] 016.Struts2 国际化配置
    [工具推荐]_iOS音频批量转换
  • 原文地址:https://www.cnblogs.com/artwl/p/2879002.html
Copyright © 2011-2022 走看看