我之前将其用于目标元素,而不是包装器,但在此示例中似乎不起作用。如果运行代码,您会看到一些奇怪的东西。即使在将包装器添加到它们之前,这些部分的offsetTops也为0。第二个奇怪的事情是,包装器似乎到达了最底端,因为它们的offsetTops是主体的offsetHeight-包装器的offsetHeight。是在window.onload内部调用该函数的问题吗?我真的不知道问题出在哪里。在所有登录到控制台的情况下,最接近的相对定位的父元素是主体。所有元素均显示为空。有人请告诉我这里发生了什么。并且请不要建议getBoundingClientRect(),因为在这种情况下它对我没有用。

window.onload = function () {
  const sections = document.querySelectorAll("section");
  let eT = [];
  for (let i = 0, len = sections.length; i < len; i++) {
      const el = sections[i];
      console.log(el.offsetTop, el.offsetParent);
      if (el.parentNode.className !== "wrapper") {
          const wrapper = document.createElement("div");
          wrapper.className = "wrapper";
          el.parentNode.appendChild(wrapper);
          wrapper.appendChild(el);
          wrapper.style.height = el.offsetHeight + "px";
          wrapper.style.position = "relative";
      }
      const elCont = document.querySelectorAll(".wrapper")[i];
      let elClone = elCont;
      eT[i] = 0;
      do {
          eT[i] += elClone.offsetTop;
          elClone = elClone.offsetParent;
      }
      while (elClone !== document.body);
      console.log(eT[i], elCont.offsetHeight, document.body.offsetHeight);
  }
}
section{
  width: 100vw;
  height: 1000px;
  position: relative;
  border: 1px solid;
}
body{
  position: relative;
}
<body>
<section></section>
<section></section>
<section></section>
<section></section>
</body>


编辑
我尝试了onscroll,并且一切正常。但是,这并不能解释为什么发生这些事情。



所以它仍然很奇怪。在使用此功能之前,还应加载此功能,但效果很好。我试图将包装器添加到元素中,并让它们获得offsetTops,然后这些事情发生了。但是,在此示例中,如果我尝试不使用包装器,则它也不起作用。而且,我没有更改我先前的(工作)代码中的任何内容,只是添加了包装器内容。

最佳答案

它只是实现问题,它的行为符合预期。请通过以下说明

/**
 * Lets go through one iteration
 * Lets name our sections S1, S2, S3, S4 for brevity
 * current DOM: body<S1 S2 S3 S4>
 */

// el = S1
if (el.parentNode.className !== "wrapper") {
    const wrapper = document.createElement("div");
    wrapper.className = "wrapper";
    el.parentNode.appendChild(wrapper);
    // At this point wrapper is the last child of body, with 4 sections above it
    // DOM: body<S1 S2 S3 S4 W>
    wrapper.appendChild(el);
    // el has been MOVED inside wrapper, and is removed from its original position
    // DOM: body<S2 S3 S4 W<S1>>
    wrapper.style.height = el.offsetHeight + "px";
    wrapper.style.position = "relative";
}

因此,在添加每个包装器之后
  • 包装之前有3个部分,因此offsetTop为3006(1002 * 3)
  • 现在已移动了最顶层的元素,下一个元素是新的最顶层的元素,因此对于下一次迭代,下一个元素的offsetTop为0。

  • 对于所有迭代,将重复相同的操作。这就是为所有节获取0 offsetTop并为所有包装器获取3006 offsetTop的原因。

    由此证明。

    关于javascript - 将包装器添加到元素,然后读取offsetTop返回错误的结果,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50787436/

    10-13 08:37