草庐IT

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

coder 2023-08-12 原文

我之前将它用于目标元素,而不是包装器,但它似乎在这个例子中不起作用。如果你运行代码,你会看到一些奇怪的东西。部分 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,一切正常。但是,它并不能解释为什么会发生这些事情。

The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images, scripts, links and sub-frames have finished loading. link

所以还是很奇怪。在我使用这个函数之前,它也被加载了,但它工作得很好。我试图给元素添加包装器,并让它们偏移到顶部,然后这些事情就发生了。但是,在这个例子中,如果我在没有包装器的情况下尝试它,它也行不通。而且,我没有更改我以前的(工作)代码中的任何内容,只是添加了包装器。

最佳答案

这只是实现问题,它的行为符合预期。请仔细阅读以下说明

/**
 * 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. wrapper 之前有 3 个部分,因此 offsetTop 为 3006 (1002 * 3)
  2. 现在移动了最顶层元素,下一个元素是新的最顶层元素,因此对于下一次迭代,下一个元素的 offsetTop 为 0。

所有迭代都将重复相同的操作。这就是为所有部分获取 0 offsetTop 并为所有包装器获取 3006 offsetTop 的原因。

因此证明。

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

有关javascript - 向元素添加包装器,然后读取 offsetTop 返回错误结果的更多相关文章

  1. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  2. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  3. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  4. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  5. ruby - 将 Bootstrap Less 添加到 Sinatra - 2

    我有一个ModularSinatra应用程序,我正在尝试将Bootstrap添加到应用程序中。get'/bootstrap/application.css'doless:"bootstrap/bootstrap"end我在views/bootstrap中有所有less文件,包括bootstrap.less。我收到这个错误:Less::ParseErrorat/bootstrap/application.css'reset.less'wasn'tfound.Bootstrap.less的第一行是://CSSReset@import"reset.less";我尝试了所有不同的路径格式,但它

  6. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  7. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  8. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

    我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

  9. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

  10. ruby - 按值降序排列散列,然后按升序键入 ruby - 2

    我有这样的哈希trial_hash={"key1"=>1000,"key2"=>34,"key3"=>500,"key4"=>500,"key5"=>500,"key6"=>500}我按值降序排列:my_hash=trial_hash.sort_by{|k,v|v}.reverse我现在是这样理解的:[["key1",1000],["key4",500],["key5",500],["key6",500],["key3",500],["key2",34]]但我希望当值相同时按键的升序排序。我该怎么做?例如:上面的散列将以这种方式排序:[["key1",1000],["key3",500

随机推荐