javascript getBoundingClientRect()值对于动态添加的元素是错误的

时间:2016-04-15 15:46:10

标签: javascript

无法在网络上找到答案,因此请在此处发布问题。

我想要实现的目标:

当用户滚动到页面的最底部时,获取最新的动态加载元素的最低值,并使用它来确定是否需要加载另一个元素。

数学很简单:

if (element.getBoundingClientRect().bottom <= window.innerHeight)
   loadAnotherElement();
  

window.innerHeight是955px

问题:

在初始加载时,第一个元素的底部值为905px,这很好并触发函数加载另一个,但是在第二个元素加载后,底部值是{{1} }永远不会触发1389px函数。

我无法发布完整的代码,因为它过于复杂,所以希望以上内容足以理解。

修改

管理以创建适当的test case

1 个答案:

答案 0 :(得分:4)

在JS小提琴中你发布了它没有识别正确高度的原因是因为你的内部元素是浮动的。浮动不会影响父元素的高度,因此我将建议以下解决方案:

article:after {
    width: 100%;
    clear: both;
    content: '';
    display: block;
}

我还清理了小提琴,删除了不必要的部分,以便更容易看出错误的位置(在您的部分之前和之后显示的表格样式没有优势)。

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>

更新

如果您希望元素整齐地保持一致,为什么还要将它们包裹在单独的元素中呢?简单地创建元素作为新的兄弟姐妹将推动其最终大小:

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>