Move items up or down depending on the scroll direction
You can use jQuery .append() and .prepend() to move items without cloning.
You will use similar methods for endless scrolling with lazy loading (AJAX), but in this case you want to handle scrolling up and down, and instead of loading new content from the server, you simply recycle the existing DOMs in the list.
Below I demonstrate one method. I save the scroll position in the cache of the .data element for easy search when determining the direction of the scroll. I decided to determine the scroll direction to avoid unnecessary variable assignments to improve performance. Otherwise, you will receive elements and do the math for the scroll event, which will not occur in this direction.
Scroll handler:
$('#right-column').on('scroll', function (e) { var $this = $(this), $results = $("#results"), scrollPosition = $this.scrollTop(); if (scrollPosition > ($this.data('scroll-position') || 0)) { // Scrolling down var threshold = $results.height() - $this.height() - $('.result:last-child').height(); if (scrollPosition > threshold) { var $firstResult = $('.result:first-child'); $results.append($firstResult); scrollPosition -= $firstResult.height(); $this.scrollTop(scrollPosition); } } else { // Scrolling up var threshold = $('.result:first-child').height(); if (scrollPosition < threshold) { var $lastResult = $('.result:last-child'); $results.prepend($lastResult); scrollPosition += $lastResult.height(); $this.scrollTop(scrollPosition); } } $this.data('scroll-position', scrollPosition) });
Full working example:
$('#right-column').on('scroll', function (e) { var $this = $(this), $results = $("#results"), scrollPosition = $this.scrollTop(); if (scrollPosition > ($this.data('scroll-position') || 0)) {
body { font-family: sans-serif; } h1 { font: bold 2rem/1 Georgia, serif; } p { line-height: 1.5; margin-bottom: 1em; } label { font-weight: bold; margin-bottom: 1em; } .column { box-sizing: border-box; float: left; width: 50%; height: 100vh; padding: 1em; overflow: auto; } #right-column { background-color: LemonChiffon; } .result { padding: 1em; cursor: pointer; } .result .main { height: 2em; font-weight: bold; line-height: 2; } .result .details { display: none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class= "column" id="left-column"> <p>Existing DOM elements are moved to the top or bottom of the list depending on your scroll direction.</p> <label>Change the number of results to display <input id="newNumber" type="number" value="10" /> </div> <div class= "column" id="right-column"> <div id="results"> <div id="result1" class="result"> <div class="main">Result 1</div> <div class="details">Details for result 1</div> </div> <div id="result2" class="result"> <div class="main">Result 2</div> <div class="details">Details for result 2</div> </div> <div id="result3" class="result"> <div class="main">Result 3</div> <div class="details">Details for result 3</div> </div> <div id="result4" class="result"> <div class="main">Result 4</div> <div class="details">Details for result 4</div> </div> <div id="result5" class="result"> <div class="main">Result 5</div> <div class="details">Details for result 5</div> </div> <div id="result6" class="result"> <div class="main">Result 6</div> <div class="details">Details for result 6</div> </div> <div id="result7" class="result"> <div class="main">Result 7</div> <div class="details">Details for result 7</div> </div> <div id="result8" class="result"> <div class="main">Result 8</div> <div class="details">Details for result 8</div> </div> <div id="result9" class="result"> <div class="main">Result 9</div> <div class="details">Details for result 9</div> </div> <div id="result10" class="result"> <div class="main">Result 10</div> <div class="details">Details for result 10</div> </div> </div> </div>
Full working example in CodePen , if you prefer.
gfullam
source share