title: jQuery removing/inserting DOM elements on scroll is finicky
body: <p>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:</p>
  
  <pre><code>$(document).ready(function() {
  
  // assign content index and parent, add to array
  
      var content = new Array();
      var index = 0;
      $('section &gt; *').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 &gt; *').remove();
  
  // insert content
  
      var firstEl = centerEl - 30;
      if (firstEl &lt; 0) {
          firstEl = 0;
      }
      var lastEl = centerEl + 30;
      if (lastEl &gt; content.length) {
          lastEl = content.length;
      }
      for (var i = firstEl; i &lt; 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 = '&lt;' + tag + ' id="' + id + '" class="' + style + '" index="' + index + '" parent="' + parent + '"&gt;' + html + '&lt;/' + tag + '&gt;';
          $('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 &gt; *').css('background-color', 'white'); // delete
          $('section &gt; *[index=' + centerEl + ']').css('background-color', 'aqua'); // delete
          // calculate what to display
          var firstEl = centerEl - 30;
          if (firstEl &lt; 0) {
              firstEl = 0;
          }
          var lastEl = centerEl + 30;
          if (lastEl &gt; content.length) {
              lastEl = content.length;
          }
          // remove elements
          $('section &gt; *').each(function() {
              var index = $(this).attr('index');
              if (index &lt; firstEl || index &gt; lastEl) {
                  $(this).remove();
              }
          });
          // add elements
          if (change &gt; 0) {
              for (var i = firstEl; i &lt;= lastEl; i++) {
                  if ($('section &gt; *[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 = '&lt;' + tag + ' id="' + id + '" class="' + style + '" index="' + index + '" parent="' + parent + '"&gt;' + html + '&lt;/' + tag + '&gt;';
                      $('section[index=' + parent + ']').append(el);
                  }
              }
          }
          if (change &lt; 0) {
              for (var i = lastEl; i &gt;= firstEl; i--) {
                  if ($('section &gt; *[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 = '&lt;' + tag + ' id="' + id + '" class="' + style + '" index="' + index + '" parent="' + parent + '"&gt;' + html + '&lt;/' + tag + '&gt;';
                      $('section[index=' + parent + ']').prepend(el);
                  }
              }
          }
      }
  }
  $(window).scroll(function() {
      loadContent();
  });
  
  });
  </code></pre>
  
  <p>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.</p>
  
  <p>My question, then, is why might the upward scrolling be less reliable than the downward? Any thoughts/guesses/suggestions?</p>