我正在为Appcelerator Titanium中的Web视图构建代码。由于网页上文本的大小(书本长度),我构建了一些jQuery,以便在用户滚动时自动删除/插入页面内容。这意味着在任何给定时间只加载了一小部分页面,因此操作内存的压力更小,渲染更平滑。这是代码:
$(document).ready(function() {
// assign content index and parent, add to array
var content = new Array();
var index = 0;
$('section > *').each(function() {
// set variables
var tag = $(this).get(0).tagName;
var id = $(this).get(0).id;
var style = $(this).get(0).className;
var parent = $(this).parent('section').attr('index');
var html = $(this).html();
// add to html
$(this).attr('parent', parent).attr('index', index);
// add to array
content[index] = new Array(tag, id, style, index, parent, html);
// next index
index++;
});
// find center element, remove elements
var midW = parseInt($(window).width() / 2);
var midH = parseInt($(window).height() / 2);
var centerEl = document.elementFromPoint(midW, midH);
if (!$(centerEl).attr('parent')) {
centerEl = $(centerEl).parent();
}
centerEl = parseInt($(centerEl).attr('index'));
$('section > *').remove();
// insert content
var firstEl = centerEl - 30;
if (firstEl < 0) {
firstEl = 0;
}
var lastEl = centerEl + 30;
if (lastEl > content.length) {
lastEl = content.length;
}
for (var i = firstEl; i < lastEl; i++) {
var tag = content[i][0];
var id = content[i][1];
var style = content[i][2];
var index = content[i][3];
var parent = content[i][4];
var html = content[i][5];
var el = '<' + tag + ' id="' + id + '" class="' + style + '" index="' + index + '" parent="' + parent + '">' + html + '</' + tag + '>';
$('section[index=' + parent + ']').append(el);
}
// on scroll
var change;
var loadContent = function() {
// find new center element
midW = parseInt($(window).width() / 2);
midH = parseInt($(window).height() / 2);
newCenterEl = document.elementFromPoint(midW, midH);
if (!$(newCenterEl).attr('parent')) {
newCenterEl = $(newCenterEl).parent();
}
newCenterEl = parseInt($(newCenterEl).attr('index'));
// if the center element has changed
if (newCenterEl != centerEl) {
// set center
if (!isNaN(newCenterEl)) {
change = newCenterEl - centerEl;
centerEl = newCenterEl;
}
$('section > *').css('background-color', 'white'); // delete
$('section > *[index=' + centerEl + ']').css('background-color', 'aqua'); // delete
// calculate what to display
var firstEl = centerEl - 30;
if (firstEl < 0) {
firstEl = 0;
}
var lastEl = centerEl + 30;
if (lastEl > content.length) {
lastEl = content.length;
}
// remove elements
$('section > *').each(function() {
var index = $(this).attr('index');
if (index < firstEl || index > lastEl) {
$(this).remove();
}
});
// add elements
if (change > 0) {
for (var i = firstEl; i <= lastEl; i++) {
if ($('section > *[index=' + i + ']').length == 0) {
var tag = content[i][0];
var id = content[i][1];
var style = content[i][2];
var index = content[i][3];
var parent = content[i][4];
var html = content[i][5];
var el = '<' + tag + ' id="' + id + '" class="' + style + '" index="' + index + '" parent="' + parent + '">' + html + '</' + tag + '>';
$('section[index=' + parent + ']').append(el);
}
}
}
if (change < 0) {
for (var i = lastEl; i >= firstEl; i--) {
if ($('section > *[index=' + i + ']').length == 0) {
var tag = content[i][0];
var id = content[i][1];
var style = content[i][2];
var index = content[i][3];
var parent = content[i][4];
var html = content[i][5];
var el = '<' + tag + ' id="' + id + '" class="' + style + '" index="' + index + '" parent="' + parent + '">' + html + '</' + tag + '>';
$('section[index=' + parent + ']').prepend(el);
}
}
}
}
}
$(window).scroll(function() {
loadContent();
});
});
总体而言,它运行良好,尤其是当用户向下滚动时。向上滚动也有效,但由于某种原因,它更加挑剔,有时会卡住。向上滚动和向下滚动之间唯一的主要区别是我在预先添加内容而不是附加内容。
那么,我的问题是,为什么向上滚动可能不如向下滚动?有什么想法/猜测/建议吗?
答案 0 :(得分:1)
这是我最终得到的代码。它工作得很好,大约是原始代码的四分之一。
$(document).ready(function() {
// assign section IDs
var sectionID = 0;
$('section').each(function() {
$(this).attr('id', 's' + sectionID);
sectionID++;
});
// assign element IDs, add to array
var content = new Array();
var contentID = 0;
$('section > *').each(function() {
$(this).attr('id', contentID);
content[contentID] = new Array($(this).parent('section').attr('id'), $(this));
contentID++;
});
// display elements
var display = function() {
// determine center
var center = parseInt($(document.elementFromPoint(parseInt($(window).width() / 2), parseInt($(window).height() / 2))).closest('section > *').attr('id'));
// determine first/last
var first, last;
if (!isNaN(center)) {
first = ((center - 20) < 0) ? 0 : (center - 20);
last = ((center + 20) > content.length) ? content.length : (center + 20);
}
// hide
$('section > *').each(function() {
var id = $(this).attr('id');
if (id < first || id > last) {
$(this).remove();
}
});
// show
var start = $('section > *').first().attr('id') - 1;
for (var i = start; i >= first; i--) {
$('section#' + content[i][0]).prepend(content[i][1]);
}
var end = parseInt($('section > *').last().attr('id')) + 1;
for (var i = end; i <= last; i++) {
$('section#' + content[i][0]).append(content[i][1]);
}
}
// listeners
$(window).load(function() {
display();
});
$(window).scroll(function() {
display();
});
});
答案 1 :(得分:0)
我的猜测如下:
prepend需要更多的渲染工作然后追加,因为插入元素之后的所有dom都应该被重建。在追加时,插入一个
后没有元素无论如何,如果你只添加/追加一次而不是50次,那么jquery可以更快地工作
for (var i = lastEl; i >= firstEl; i--) {
if ($('section > *[index=' + i + ']').length == 0) {
var tag = content[i][0];
var id = content[i][1];
var style = content[i][2];
var index = content[i][3];
var parent = content[i][4];
var html = content[i][5];
var el = '<' + tag + ' id="' + id + '" class="' + style + '" index="' + index + '" parent="' + parent + '">' + html + '</' + tag + '>';
$('section[index=' + parent + ']').prepend(el);
}
}
你应该重写这个块,以便最小化前缀的数量
我想你没有很多部分,所以你可以做这样的事情
var sections={};
{ //your loop starts here
if (typeof sections[parent]=='undefined'){
sections[parent]=[];
}
var el=all+your+stuff;
sections[parent].push(el);
}//ends here
$(sections).each(function(parent,section){
$('section[index=' + parent + ']').prepend(section);
});
我想你会改变一些东西,以适应你的代码,但这是个主意 - &gt;最小化dom更改操作的数量,准备一堆元素并将它们全部插入