您的位置:首页 > 其它

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

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

  首先要做的就是添加拖动滚动条时的事件,另外由于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下均正常显示,如果大家有更好方案,欢迎分享。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐