滚动时,如果 offsetTop 是 >= element 做一些事情

When scrolling, if offsetTop is >= element do something

我的页面有一个图像 (#braille),当滚动 0 时,它位于 position:absolute,当滚动 > 0 时,它位于 position:fixed。当滚动 > 900 时,一些其他元素淡入。我要做的是使 #braille 图像 "stop" 在滚动时出现的 2 个元素之间(将 position:fixed 改回position:absolutetop:something 允许它正确定位在 2 个元素之间)。

我认为如果你看一下我创建的 JSFiddle 会更清楚(我在滚动时 #braille 图像应该停止的地方添加了一个文本):

http://jsfiddle.net/multiformeingegno/vde7ym94/7/

这是 JS 脚本:

$(function () {
    var timeoutId = null;

    // hide by default the arrow, the music sheet, the phrase and the yellow circle
    $('#ombra, #logopiano,#presentazione, #frase').hide();
    $("#braille").css({
        "position": "absolute",
            "top": "-56px",
            "left": 0,
            "margin": 0
    });
    $("#ombra").css({
        "top": "-56px"
    }).show();
    var w = $(window).height();
    var c = $("#homescroll").height();
    $("#homescroll").css({
        "height": w + 44 + "px"
    });

    // define the arrow
    var $freccia = $('#freccia1');

    // define the braille shadow
    var $ombra = $('#ombra');

    // define the music sheet image
    var $logopiano = $('#logopiano');

    // define the phrase and the yellow circle
    var $presentazionefrase = $('#presentazione, #frase');
    $(window).scroll(function () {
        scroll = $(window).scrollTop();


        if (scroll >= 900) {
            // events firing when scrolling down
            $("#intro").hide();
            $freccia.fadeOut('slow');
            $ombra.fadeOut('slow');
            $logopiano.fadeIn('slow');
            clearTimeout(timeoutId);
            timeoutId = setTimeout(function () {
                $presentazionefrase.fadeIn('slow');
            }, 500);


        } else {
            // events firing when scrolling (back) up
            clearTimeout(timeoutId);
            $("#intro").show();
            if (scroll === 0) {
                $presentazionefrase.hide();
                $freccia.fadeIn('slow');
                $("#braille").css({
                    "position": "absolute"
                });
            } else {
                $("#braille").css({
                    "position": "fixed",
                        "margin": "auto",
                        "right": 0,
                        "top": "-56px"
                });
            };
            $logopiano.fadeOut('slow');
            if ($presentazionefrase.css('display') === "block") {
                $presentazionefrase.fadeOut('slow');
            }
            // make the braille shadow image visible only when at the top of the page
            if (scroll < 10) {
                $ombra.fadeIn('slow');
            } else {
                $ombra.fadeOut('slow');

            }

        }
    });
});

我以为我可以做这样的事情,但它不起作用:

if ($("#braille").offset().top >= $("#frase").offset().top) {
    $("#braille").css({
        "position": "absolute",
            "top": $("#frase").offset().top + "px",

    });
};

问题是这应该适用于所有分辨率...这就是为什么我认为我可以解决计算盲文图像与 #frase 元素的偏移量的原因。

当您尝试获取 $("#frase").offset().top 时,值可能不正确,因为 $("#frase") 元素在某些时刻具有 CSS display:none,由于使用showhidefadeInfadeout

.offset() 函数无法 return 正确偏移隐藏元素。您可以考虑使用 visibilityopacity 来实现 show/hide 技巧。

Note: jQuery does not support getting the offset coordinates of hidden elements or accounting for borders, margins, or padding set on the body element.

While it is possible to get the coordinates of elements with visibility:hidden set, display:none is excluded from the rendering tree and thus has a position that is undefined.

试试:

if ($("#braille").offset().top + $("#braille").height() >= $("#logopianocontainer").offset().top + 90) {
        $("#braille").css({
            "position": "absolute",
            "top": $("#logopianocontainer").offset().top -  $("#braille").height() + 90 + "px"
        });
    };

Here a working jsfidlle

请注意,我使用 $("#logopianocontainer") 而不是 $("#frase") 那是因为 #frase#braille 到达 [= 的位置时有 display: none 17=] 所以它的 .offset().top 计算错误。

另一方面请注意元素高度的使用,因为当您比较 $("#braille").offset().top >= $("#logopianocontainer").offset().top 时,这将在元素顶部和您想要知道 img 底部的时间之间进行比较到达 $("#logopianocontainer") 的位置,然后将 $("#braille") 的顶部设置在 $("#logopianocontainer").offset().top - $("#braille").height() 的位置。90 值是将 img 定位在其他两个元素中间的估计值。

避免跳跃

我发现 img 跳转的原因,是因为当滚动小于 900 时,您再次从绝对切换到固定(向上滚动)并且有一个范围 #braille 在应该固定时固定是绝对的,当通过范围时,它会跳转到该位置。

看这里

if (scroll >= 900) {
        // events firing when scrolling down
} 
else {
        // events firing when scrolling (back) up

        if (scroll === 0) {
            ...
        } 
        else {
            $("#braille").css({
                "position": "fixed",
                    "margin": "auto",
                    "right": 0,
                    "top": "-56px"
        });
};

所以你可以设置一个更具体的值(950 看起来不错)或者让它更动态,例如当 #braille 定位到绝对放置一个变量来跟踪向下滚动时向下移动了多远然后当向上滚动时,减小变量,当变量小于 0 时,你再次将 #braille 切换到 fixed,这只是一个想法,它可能比这更复杂。