【问题标题】:getBoundingClientRect() returns same values for all children if first child has any negative value如果第一个孩子有任何负值,getBoundingClientRect() 为所有孩子返回相同的值
【发布时间】:2017-08-05 02:38:08
【问题描述】:

背景

我正在构建一个无限水平的图像滚动:

<div class="infinite-thumbs">
    <img src="1.jpg" class="thumb thumb-one">
    <img src="2.jpg" class="thumb thumb-two">
    <img src="3.jpg" class="thumb thumb-three">
    ...
    <img src="10.jpg" class="thumb thumb-ten">
</div>

<style lang="stylus">

    .infinite-thumbs
        position absolute
        width 100%
        height 180px
        bottom 40px
        white-space nowrap
        overflow auto
        overflow-y hidden

    .thumb
        position relative
        display inline-block
        width 200px
        height 180px

</style>

在此处了解有关触控笔的更多信息:stylus-lang.com


然后我有一些jQuery/JS 来处理图像在屏幕外时的克隆和附加:

function scrollUpdate() {

    $('.thumb').each(function() {

        var bounding = $(this)[0].getBoundingClientRect();

        if (bounding.right < 0) {
            var $el = $(this);
            $el.clone(true).appendTo('.infinite-thumbs');
            $el.remove();
        }

    });

}

$('.infinite-thumbs').on('scroll', function () {
    window.requestAnimationFrame(scrollUpdate);
});

所以scrollUpdate() 循环遍历每个.thumb 元素并检查它是否在屏幕上可见。如果不是 (bounding.right &lt; 0),则将其克隆并附加到 .infinite-thumbs 元素的末尾。



问题

我遇到的问题是,一旦.thumb 元素之一为bounding.right 返回负值所有.thumb 元素返回完全相同的一组bounding 值。

所以当一切都可见时,我会在我的控制台中得到这个:

.thumb-one: { top : 0, right : 200, ... }
.thumb-two: { top : 0, right : 400, ... }
.thumb-three: { top : 0, right : 600, ... }
...
.thumb-ten: { top : 0, right : 2000, ... }

但只要第一个子元素 (.thumb-one) 获得负的 bounding.right 值,我就会在控制台中得到这个:

.thumb-one: { top : 0, right : -1, ... }
.thumb-two: { top : 0, right : -1, ... }
.thumb-three: { top : 0, right : -1, ... }
...
.thumb-ten: { top : 0, right : -1, ... }

什么给了?为什么它们都返回一个具有完全相同值的 bounding 对象,只是因为其中一个不在屏幕上?

有人知道这里发生了什么吗?



注意:

$.fn.offset()$.fn.position() 的行为方式与 getBoundingClientRect();它们为每个返回相同的一组值 .thumb 一旦.thumb-one 的结果为负值。

【问题讨论】:

    标签: javascript jquery getboundingclientrect


    【解决方案1】:

    这是因为您在检查所有拇指位置之前删除了元素。删除第一个元素会导致下一个元素成为第一个元素,离开屏幕。这样,每个拇指都将呈现相同的“正确”位置。

    解决方案 在“每个”循环之外创建一个临时数组,并使用它来保存屏幕外拇指。然后,在循环之后,以与之前相同的方式克隆、删除和附加元素。像这样的:

    function scrollUpdate() {
        var offScreenElements = [];
        $('.thumb').each(function() {
    
            var bounding = $(this)[0].getBoundingClientRect();
    
            if (bounding.right < 0) {
                offScreenElements.push($(this));
            }
        });
        $.each(offScreenElements, function(index, element) {
            element.clone(true).appendTo('.infinite-thumbs');
            element.remove();
        });
    }
    

    【讨论】:

    • 通过禁用$.fn.clone()$.fn.remove() 进行快速测试表明您正在做某事!我会追这个...
    • 我添加了一些代码(未经测试,但我认为您可以使用它来实现您的目标)
    • 像魅力一样工作!谢谢阿尔贝托,让我免于在那里发疯;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-22
    • 1970-01-01
    • 2022-06-28
    • 1970-01-01
    • 2012-06-13
    • 2017-03-11
    • 1970-01-01
    相关资源
    最近更新 更多