两个DIV的同步位置

时间:2018-08-29 15:41:38

标签: javascript requestanimationframe

在某些情况下,我需要将一个DIV放置在另一个DIV的下面,就像工具提示一样。它必须位于单独的容器中(门户模式)。我的问题是,如果我在requestAnimationFrame中这样做—在回调时,如果我调用getBoundingClientRect来计算位置,我会从上一帧获取旧位置,而尚未计算出新位置。至少在我看来是如此。因此,当用户滚动页面时,有时帧的位置明显不正确。您必须在Chrome中快速上下滚动才能注意到它。在IE11中,情况变得更糟,即使在随后的CSS动画中,每一帧都不正确,甚至落后一帧。

我创建了一个简单的codepen,在其中尝试跟随移动的“鸭子”进行下拉菜单: https://codepen.io/waterplea/pen/gdwQGK

var dropdown = document.querySelector('.dropdown');
var duck = document.querySelector('.duck');
var host = document.querySelector('.host');

requestAnimationFrame(position);

function position() {
  var duckRect = duck.getBoundingClientRect();
  var hostRect = host.getBoundingClientRect();

  dropdown.style.top = duckRect.top + duckRect.height - hostRect.top + 'px';
  dropdown.style.left = duckRect.left - hostRect.left + 'px';

  requestAnimationFrame(position);
}

Codepens在IE中不起作用,因此这是工作调试视图的链接,以尝试查看IE中的滞后: https://s.codepen.io/waterplea/debug/gdwQGK/DqrDdKgDjVXr

所以我的问题是-如何使我的DIV保持同步?当已经知道DIV的即将到来的位置时,如何运行我的代码?

编辑:以下是Mac上始终可复制的屏幕截图: https://jmp.sh/v/KJ9ndWhBPPQem49wfChm

1 个答案:

答案 0 :(得分:0)

您可以使原始主机不可见并在其上方有两个叠加层。第一个将复制主机的内容(这次可见),第二个将是您的鸭子负载。然后这两个叠加层应该同步滚动。

透明主机需要存在以建立您可以稍后阅读的自然大小。如果大小已知,您可以使用空的 div 代替它。

这对仍然会在页面内容后面滚动一帧,但至少覆盖不会严重阻碍可见主机。

相关问题