I’m building code for a web view in Appcelerator Titanium. Because of the massive (book length) size of the text on the webpage, I’ve built some jQuery to automatically remove/insert the page’s content as the user scrolls. This means that only a small portion of the page is loaded at any given time, so there is a lot less stress on operating memory and much smoother rendering. Here’s the code:
$(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();
});
});
Overall, it’s working well, especially when the user scrolls down. Scrolling up also works, but for some reason it’s much more finicky, and sometimes it gets stuck. The only major difference between scrolling up and scrolling down is that I’m prepending the content instead of appending it.
My question, then, is why might the upward scrolling be less reliable than the downward? Any thoughts/guesses/suggestions?
This is the code I ended up with. It’s working perfectly, and it’s about a quarter of the size of the original code.