jQuery在scroll上删除/插入DOM元素很挑剔
我正在Appcelerator Titanium中构建web视图的代码。由于网页上文本的巨大(书籍长度),我构建了一些jQuery,可以在用户滚动时自动删除/插入页面内容。这意味着在任何给定的时间都只加载页面的一小部分,因此操作内存的压力小得多,渲染也更平滑。代码如下:jQuery在scroll上删除/插入DOM元素很挑剔,jquery,webview,appcelerator,Jquery,Webview,Appcelerator,我正在Appcelerator Titanium中构建web视图的代码。由于网页上文本的巨大(书籍长度),我构建了一些jQuery,可以在用户滚动时自动删除/插入页面内容。这意味着在任何给定的时间都只加载页面的一小部分,因此操作内存的压力小得多,渲染也更平滑。代码如下: $(document).ready(function() { // assign content index and parent, add to array var content = new Array();
$(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();
});
});
$(文档).ready(函数(){
//分配内容索引和父级,添加到数组
var content=新数组();
var指数=0;
$('section>*')。每个(函数(){
//设置变量
var标记=$(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();
//添加到html
$(this.attr('parent',parent).attr('index',index);
//添加到数组
内容[索引]=新数组(标记、id、样式、索引、父项、html);
//下一个索引
索引++;
});
//查找中心元素,删除元素
var midW=parseInt($(窗口).width()/2);
var midH=parseInt($(窗口).height()/2);
var centerEl=document.elementFromPoint(中间、中间);
if(!$(centerEl.attr('parent')){
centerEl=$(centerEl.parent();
}
centerEl=parseInt($(centerEl.attr('index'));
$('section>*')。删除();
//插入内容
var firstEl=中心线-30;
if(firstEl<0){
firstEl=0;
}
var lastEl=中心线+30;
if(lastEl>content.length){
lastEl=content.length;
}
for(var i=firstEl;i*').css('background-color','white');//删除
$('section>*[index='+centerEl+']')。css('background-color','aqua');//删除
//计算要显示的内容
var firstEl=中心线-30;
if(firstEl<0){
firstEl=0;
}
var lastEl=中心线+30;
if(lastEl>content.length){
lastEl=content.length;
}
//删除元素
$('section>*')。每个(函数(){
var index=$(this.attr('index');
如果(索引lastEl){
$(this.remove();
}
});
//添加元素
如果(更改>0){
for(var i=firstEl;i=firstEl;i--){
如果($('section>*[index='+i+']')。长度==0){
var tag=含量[i][0];
var id=含量[i][1];
var style=内容[i][2];
var指数=含量[i][3];
var parent=含量[i][4];
var html=内容[i][5];
var el=''+html+'';
$('section[index='+parent+']')。前置字符(el);
}
}
}
}
}
$(窗口)。滚动(函数(){
loadContent();
});
});
总的来说,它工作得很好,尤其是当用户向下滚动时。向上滚动也可以,但由于某些原因,它更挑剔,有时会卡住。向上滚动和向下滚动之间唯一的主要区别是,我是在预先添加内容,而不是附加内容
那么,我的问题是,为什么向上滚动比向下滚动更不可靠?有什么想法/猜测/建议吗?我的猜测如下:
由于插入元素之后的所有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);
}
}
我想你会改变一些东西,以适应你的代码,但这是idea->最小化dom更改操作的数量,准备一堆元素并将它们全部插入到一起这就是我最终得到的代码。它工作得很好,大约是原始代码的四分之一大小
$(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();
});
});
$(文档).ready(函数(){
//分配节ID
var-sectionID=0;
$('section')。每个(函数(){
$(this.attr('id','s'+sectionID);
sectionID++;
});
//分配元素ID,添加到数组
var content=新数组();
var-contentID=0;
$('section>*')。每个(函数(){
$(this.attr('id',contentID);
content[contentID]=新数组($(this).parent('section').attr('id'),$(this));
contentID++;
});
//显示元素
变量显示=函数(){
//确定中心
var center=parseInt($(document.elementFromPoint(parseInt($(window.width()/2)、parseInt($(window.height()/2))).closest('section>*').attr('id');
//确定第一个/最后一个
var第一,最后;
如果(!isNaN(中间)){
第一个=((中心-20)<0)?0:(中心-20);
last=((中心+20)>content.length)?content.length:(中心+20);
}
//隐藏
$(
$(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();
});
});