【问题标题】:Intersection observer does not work with target with position: fixed交叉点观察器不适用于具有位置的目标:固定
【发布时间】:2018-03-20 16:16:30
【问题描述】:

我正在尝试通过交叉点观察器调用回调。

我希望 target 成为 style: "position: fixed" 并通过 style.top

我还用style: "position: relative" 指定了作为目标祖先的根元素。

但是当目标和观察者相交时,不会触发回调函数。

我错过了一些限制吗?

这是我输入的内容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>IO</title>
</head>
<body>
<div style="height: 200px;width: 100%;background: violet" class="upper">aaa</div>
<div style="position:relative;height: 200px;width: 100%;background: blueviolet" id="middle">bbb
    <div id="target" style="position:fixed;top: 0px;width: 50px;height: 50px;background: firebrick">ccc</div>
</div>
<script>
    let options = {
        root: document.getElementById("middle"),
        rootMargin: '0px',
        threshold: 0
    };
    let observer = new IntersectionObserver(entry => {
        console.log("observer's acting.")
    }, options);

    let target = document.getElementById("target");
    observer.observe(target);

    let stepping = 0;

    let cb = () => {
        target.style.top = stepping + 'px';
        stepping += 4;
        if (stepping < 300){
            setTimeout(cb, 100);
        }
    };

    window.addEventListener("click", () => {
        cb();
    })
</script>
</body>
</html>

这是一个 codepen 演示: codepen demo

您可以单击页面中的任意位置开始移动ccc 块。

【问题讨论】:

    标签: javascript intersection-observer


    【解决方案1】:

    带有position: fixed 的元素相对于视口定位并且视口移动。因此,固定定位的元素会在您滚动时“移动”。即使#target#middle 的孩子,我相信IntersectionObserver,无论它在后台使用什么来计算target 是否进入/离开root,都不会触发回调,因为target在文档流之外。

    这是一个相关的问题。与此问题相关的互联网信息不多:https://bugs.chromium.org/p/chromium/issues/detail?id=653240

    注意:在目标上设置position: absolute 确实会在进入和离开视口时触发回调。

    【讨论】:

    • 在我自己的测试中,如果根是视口,似乎position: absolute 的工作方式与您希望的一样,但是如果您检查与另一个元素的交集,它与fixed 有相同的问题。我在某处看到了一些关于这个的语言,指出两个观察到的元素必须在同一个“区块链”中;大概这意味着两者都不允许使用fixedabsolute 中断渲染流。这是一种耻辱,因为绝对元素和相对元素之间的碰撞是想要检测的常见事情。我想这些情况又回到了旧的方式。
    • 这是真的吗?我正在尝试使用 Intersection Observer 检测使用绝对定位的幻灯片上的可见性。这是浪费时间吗?
    • @MattiasMartens 看来我遇到了同样的障碍......位置:未检测到溢出容器内的绝对值,仅检测到整个视口。处理这个问题的第二好的方法是什么,getBoundingClientRect
    • @Perp 是的,如果我没记错的话,这就是我所指的。在我的情况下,我能够避免需要它,但我想您可能希望使用 setInterval() 定期监视它,或者将侦听器附加到窗口调整大小事件、滚动事件以及代码中可能更改尺寸或位置的任何内容的元素。
    • 为了完整起见,我想确认 position: absolute 正在与 Intersection Observer 合作,我只是执行错误。对于任何阅读本文的人来说,这肯定不是问题。
    【解决方案2】:

    在我的例子中,我的根元素(位置:固定)与我想要观察的元素(可滚动)处于相同的 DOM 层次结构级别,并且没有触发任何事件。

    <div id="root" style="position:fixed"></div>
    <div id="scrollable"></div>
    

    当我将元素放入根目录时,事件触发。

    <div id="root" style="position:fixed">
      <div id="scrollable"></div>
    </div>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-20
      • 1970-01-01
      相关资源
      最近更新 更多