向元素添加包装器,然后读取offsetTop会返回错误的结果

时间:2018-06-10 19:42:49

标签: javascript html css

我之前使用过这个目标元素,而不是包装器,但似乎它在这个例子中不起作用。如果你运行代码,你会看到一些奇怪的东西。即使在包装器添加到它们之前,offsetTops部分也是0。第二个奇怪的事情似乎是包装器到达最底层,因为它们offsetTops是body的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);
  }
}
&#13;
section{
  width: 100vw;
  height: 1000px;
  position: relative;
  border: 1px solid;
}
body{
  position: relative;
}
&#13;
<body>
<section></section>
<section></section>
<section></section>
<section></section>
</body>
&#13;
&#13;
&#13;

修改的 我尝试使用onscroll,一切正常。但是,它并没有解释为什么会发生这些事情。

  

加载事件在文档加载过程结束时触发。此时,文档中的所有对象都在DOM中,并且所有图像,脚本,链接和子帧都已完成加载。 link

所以它仍然很奇怪。在我使用之前,这个功能也是onload,但它工作正常。我试图在元素中添加包装器,并将它们设为offsetTops,然后发生了这些事情。但是,在这个例子中,如果我在没有包装的情况下尝试它,它也不起作用。并且,我在以前的(工作)代码中没有任何改变,只是添加了包装器。

1 个答案:

答案 0 :(得分:0)

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

/**
 * 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";
}

因此,在添加每个包装器之后

  1. 在包装之前有3个部分,因此offsetTop为3006(1002 * 3)
  2. 现在最上面的元素被移动了,下一个元素是新的最上面的元素,因此对于下一次迭代,下一个元素的offsetTop为0。

所有迭代将重复相同的操作。这就是为所有节获得0 offsetTop并为所有包装获得3006 offsetTop的原因。

因此证明。