getBoundingClientRect().left 返回错误值吗?

Boe*_*oel 5 javascript css

我想在 li 元素开始的地方放置一个 div“.indicator”,例如,如果我想相对于第二个 li 定位 div,我会这样做:

indicator.style.left = li[1].getBoundingClientRect().left+"px";
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

indicator.style.left = li[1].getBoundingClientRect().left+"px";
Run Code Online (Sandbox Code Playgroud)
var li = document.querySelectorAll(".ulcontainer > li");

var indicator = document.querySelector(".indicator");

indicator.style.left = li[1].getBoundingClientRect().left+"px";
Run Code Online (Sandbox Code Playgroud)
html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}
.ulcontainer {
    white-space: nowrap;
    padding: 0;
    position: relative;
}
.ulcontainer li {
    list-style: none;
    display: inline-block;
    border: 1px solid;
    padding: 0 20px;
}

.indicator {
    background-color: red;
    display: inline-block;
    position: relative;
}
Run Code Online (Sandbox Code Playgroud)

问题是 div getBoundingClientRect().left 没有为 li 元素返回正确的值。如果您运行该示例,您将看到“.indicator”不在当前 li 的开头。

为什么 getBoundingClientRect().left 不返回当前值?

Ric*_*ock 7

.indicator相对定位。因此,任何偏移都将相对于其默认位置,而不是相对于浏览器窗口。(相比之下,固定位置几乎总是相对于浏览器窗口,而绝对位置相对于最近定位的祖先——通常是浏览器窗口。)

由于.indicator是块级元素,其直接父元素是文档正文,因此其默认左位置等于文档正文的左边距。

将 body margin 设置为 0,它将对齐:

var li = document.querySelectorAll(".ulcontainer > li");

var indicator = document.querySelector(".indicator");

indicator.style.left = li[1].getBoundingClientRect().left+"px";
Run Code Online (Sandbox Code Playgroud)
body {
  margin: 0;
}
html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}
.ulcontainer {
    white-space: nowrap;
    padding: 0;
    position: relative;
}
.ulcontainer li {
    list-style: none;
    display: inline-block;
    border: 1px solid;
    padding: 0 20px;
}

.indicator {
    background-color: red;
    display: inline-block;
    position: relative;
}
Run Code Online (Sandbox Code Playgroud)
<ul class="ulcontainer">
    <li>OPTION 1</li><li>OPTION 2</li><li>OPTION 3</li>
</ul>
<div class="indicator">indicator</div>
Run Code Online (Sandbox Code Playgroud)