1

i am trying to build a function that when you scroll to the bottom of the page it runs a function to load in more items on a page.

I started by putting in a div with no content

<div id="loadMore"></div>

and then i found on here another function that looks at the scroll

function isScrolledIntoView(elem)
{
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();
    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    console.log(docViewTop, docViewBottom, elemTop, elemBottom);
    return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom) && (elemBottom <= docViewBottom) && (elemTop >= docViewTop));

}

$(window).scroll(function() {   

    if(isScrolledIntoView($('#loadMore')))
    {
        alert("reached");
        return false;

    }    
});

one problem is it seems to alert reached too soon and the other main problem is that it alerts "reached" back to the screen so many times - this is obviously bad because I would only want the function to run once...

then it would load in the other content and if the bottom of the page was reached again then the function (alert in eg) would run again

am i going about this the best way? and can anyone help?

thanks

4

2 回答 2

6

When working with the scroll function you need to be careful as the event is triggered once for every pixel scrolled. Therefore you need to use a timeout to only call the function when scrolling has stopped.

Try this example:

let $window = $(window);
let scrollTimer = null;

let isScrolledIntoView = (elem) => {
  let $elem = $(elem);
  let docViewTop = $window.scrollTop();
  let docViewBottom = docViewTop + $window.height();
  let elemTop = $elem.offset().top;
  let elemBottom = elemTop + $elem.height();

  console.log(docViewTop, docViewBottom, elemTop, elemBottom);
  return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom) && (elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

$(window).scroll(function() {
  clearTimeout(scrollTimer);

  scrollTimer = setTimeout(function() {
    if (isScrolledIntoView($('#loadMore'))) {
      console.log("'Reached' element is visible");
    }
  }, 100);
});
.spacer {
  height: 2000px;
  border-left: 2px solid #C00;
  margin-left: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
Scroll down...
<div class="spacer"></div>
<div id="loadMore">Reached</div>
<div class="spacer"></div>

Note that the pattern of delaying the action until after repeated scrolling has finished is called 'debouncing'.

于 2013-10-24T09:16:19.073 回答
1

你应该只绑定一次你的函数。向页面添加新项目后,您可以检查是否有更多项目可用并再次重新绑定此功能。

var addNewContent = function () {
    // get new data
    // append new data
    $('#content').prepend($('<div style="height: 1000px;">some content</div>'));

    // rebind the event, if still more data is available
    $('#content').one( 'endofcontent', addNewContent);
};

$('#content').one("endofcontent", addNewContent);

$(window,document).scroll(function() {

    if(isScrolledIntoView($('#loadMore'))) {
        $('#content').trigger("endofcontent");
        return false;
    }
});

测试它: http: //fiddle.jshell.net/d5CSd/

于 2013-10-24T09:46:43.333 回答