Not able to find an answer on wide web so posting the question here.
What I am trying to achieve:
When the user scrolls to the very bottom of the page get the latest dynamically loaded element's bottom value and use it to find out if it is time to load another one.
The math is simple:
if (element.getBoundingClientRect().bottom <= window.innerHeight)
loadAnotherElement();
window.innerHeight is 955px
The problem:
On initial load the the first element's bottom value is 905px
which is fine and trigger the function to load another one, but after the second one is loaded in the bottom value is 1389px
which will never trigger the loadAnotherElement
function.
I am not able to post full code as it is too complicated so hope the above will be enough to understand.
EDIT
Managed to create a proper test case
The "getBoundingClientRect is not a function" error occurs for multiple reasons: calling the getBoundingClientRect() method on a value that is not a DOM element. placing the JS script tag above the code that declares the DOM elements. misspelling getBoundingClientRect (it's case sensitive).
getBoundingClientRect() method returns a DOMRect object providing information about the size of an element and its position relative to the viewport.
margin is not included.
In the JS fiddle you posted the reason it was not recognising the correct height is because your inner elements are floating. A float does not contribute to the height of the parent element, so I will suggest the following solution:
article:after {
width: 100%;
clear: both;
content: '';
display: block;
}
I have also cleaned up the fiddle a bit an removed the unnecessary parts so it's easier to see where the mistake was (there was no advantage to the table style displayed before and after on your section).
var last = document.querySelector('article');
document.addEventListener('scroll', function(){
if(last.getBoundingClientRect().bottom <= window.innerHeight){
var newElement = last.cloneNode(true);
last.parentNode.appendChild(newElement);
last = newElement;
}
});
html,
body {
height: 100%;
}
/* I have removed a bit of CSS that I think didn't really do anything at all. */
article {
width: 100%;
display: inline-block;
border-bottom: 1px solid red;
}
/* This will create an element that will clear past the floats, stretching your article to the correct encapsulating size */
article:after {
width: 100%;
clear: both;
content: '';
display: block;
}
/* Some correction so they all stay neatly in line */
div {
float: left;
width: 30%;
margin: 1.5%;
height: 100vh;
position: relative;
background: blue;
}
div:nth-child(3n-2){ background: #666; }
div:nth-child(3n-1){ background: #888; }
div:nth-child(3n){ background: #222; }
<section>
<article>
<!-- I made these 6 divs so they neatly pack six in an article. -->
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</article>
</section>
If you want the elements to neatly stay in line, why bother wrapping them in seperate elements? Simple create the elements as new siblings which will push its final size:
var section = document.querySelector('section');
var article = document.querySelector('article');
document.addEventListener('scroll', function(){
if(section.getBoundingClientRect().bottom <= window.innerHeight){
section.appendChild(article.cloneNode(true));
}
});
html,
body {
height: 100%;
}
/* I have removed a bit of CSS that I think didn't really do anything at all. */
section {
width: 100%;
display: inline-block;
border-bottom: 1px solid red;
}
/* This will create an element that will clear past the floats, stretching your article to the correct encapsulating size */
section:after {
width: 100%;
clear: both;
content: '';
display: block;
}
/* Some correction so they all stay neatly in line */
div {
float: left;
width: 30%;
margin: 1.5%;
height: 100vh;
position: relative;
background: blue;
}
div:nth-child(3n-2){ background: #666; }
div:nth-child(3n-1){ background: #888; }
div:nth-child(3n){ background: #222; }
<section>
<article>
<!-- I made these 7 divs for illustrations sake. -->
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</article>
</section>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With