element.getboundingclientrect()未获取元素的正确位置

goucqfw6  于 2021-09-13  发布在  Java
关注(0)|答案(2)|浏览(391)

我试图使用element.getboundingclientrect()在单击的元素和“#identifier”之间划一条线。element.getboundingclientrect()无法获取元素的实际坐标,因为页面上的某些其他元素是相对定位的。当我试图注解掉“#header”和“#greytext”元素时,该行的显示与预期一致。页面上的其他元素会影响getboundingclientrect()坐标吗?
这是我的密码:
未对齐的线:https://jsfiddle.net/sampathperoxide/jdyoz3r4/34/
注解掉“#标题”和“#greytext”后的对齐行:https://jsfiddle.net/sampathperoxide/kqfjvs04/7/
有人能解释一下为什么“#header”和“#greytext”元素会干扰“#identifier”坐标吗?

<style>
@import url('https://fonts.googleapis.com/css2?family=Ubuntu:wght@300;400;500;700&display=swap');

html,
body {
  font-family: 'Ubuntu', sans-serif;
  background-color: lightblue;
  color: #000;
}

# content {

  color: #787878;
}

.container-fluid-child {
  background-color: #fff;
  position: relative;
  padding: 5%;
}

.container-fluid-innerchild {
  background-color: #fff;
  position: relative;
  border-radius: 25px;
}

.text-white {
  color: #fff;
}

.car-image {
  width: 35%;
  max-width: 35%;
  border: 1px solid #000;
}

.step-one {
  width: 130px;
  height: 130px;
  background-color: #81a1b6;
  color: #fff;
  justify-content: center;
  align-items: center;
  display: flex;
  border-radius: 50%;
}

.sound-icon {
  width: 20px;
  float: left;
  margin-right: 10px;
}

.set-sound {
  position: absolute;
  top: 2.4em;
  width: 100%;
}

.intro-para {
  position: absolute;
  width: 35%;
  font-size: 1.2em;
}

.hyperlink {
  color: #fff;
  text-decoration: none;
  font-size: 1.3em;
}

.hyperlink:hover {
  color: #fff;
  font-weight: 900;
  text-decoration: none;
}

.hyperlink:focus {
  color: #fff;
  text-decoration: none;
}

.footer {
  padding: 1em;
}

.text-over-image {
  float: left;
  position: absolute;
  bottom: 23em;
  left: 5em;
}

.relative {
  position: relative;
}

.textonimage {
  position: absolute;
  max-width: 30%;
  top: 2%;
  font-weight: 600;
}

.ableft {
  left: 1em;
}

.abright {
  right: 1em;
}

.car {
  cursor: pointer;
}

.grey {
  color: grey;
  font-weight: 600;
  margin-left: 1.5em;
  max-width: 50%;
  position: relative;
  top: 1em;
}

.no-padding {
  padding: 0px;
}

.firstcar-detail {
  border-radius: 25px;
}

# hr {

  -moz-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  -webkit-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  transform: rotate(-45deg);
  top: 12%;
  left: 18%;
  height: 20%;
  background-color: #000;
  width: 1px;
  position: absolute;

}

# hrtext {

  position: absolute;
  bottom: 85%;
  left: 5%;
}

.series-ul li {
  list-style: none;
  color: grey;
  font-size: 1em;
  font-weight: 600;
  border: 2px solid grey;
  display: table;
  padding: 0.3em 0.1em;
  text-align: center;
  margin: 0.5em;
  cursor: pointer;
}

.series-div {
  position: absolute;
  left: 65%;
  top: 0em;
}

.identifier {
  width: 10px;
  height: 10px;
  background-color: red;
  position: absolute;
  right: 45%;
  top: 30%;
}

# line {

  position: absolute;
  width: 2px;
  margin-top: -1px;
  background-color: red;
}

.fullwidth-img {
  width: 100%;
}

.width70-img {
  width: 90%;
  margin: 0px auto;
  margin-top: 10%;
}

.margintop10 {
  margin-top: 10%;
}

.hide {
  display: none;
}

.pointer {
  cursor: pointer;
}

.bottom-text {
  position: absolute;
  bottom: 5%;
  left: 5%;
  max-width: 15%;
}

@media only screen and (max-width: 1024px) {
  .series-ul li {
    font-size: 1em;
    min-width: auto;
  }

  .grey {
    max-width: 100%;
    font-size: 1.5em;
    top: auto;
  }

  .header .text-right {
    text-align: center;
    font-size: 2em;
  }

  .set-sound {
    top: 4em;
  }

  .bottom-text {
    bottom: 0%;
    max-width: 100%;
  }

  .intro-para {
    position: relative;
    width: 100%;
    text-align: center;
  }

  .textonimage {
    bottom: 100%;
    top: auto;
  }
}

</style>
    <div class="container-fluid">

        <div id="header"><div class="row  header">
        <div class="col-md-12 col-sm-12 col-xs-12">
            <div class="col-md-8 col-sm-8 col-xs-8"> <h1 class="text-right">Some dummy placeholder - Random text </h1></div>
            <div class="col-md-4 col-sm-4 col-xs-4">
                <div class="set-sound">
                    <img src="images/icons8-sound-50.png" class="img-responsive sound-icon hide">

            <p>Some dummy placeholder</p>
                </div>
            </div>
        </div>
    </div>
    </div>
        <div id="content"><div class="container-fluid-innerchild">
           <div class="row">
    <div class="col-md-12 col-sm-12 col-xs-12">
        <div class="col-md-7 col-sm-7 col-xs-7 no-padding">
            <div id="greytext">
                <h2 class="grey">Some dummy placeholder - Random text</h2>
            </div>
            <br>
         <div class="relative">
        <div >
            <div id="hrtext"><p>Some dummy placeholder
        </p></div>

        <div id="hr"></div>
    </div>
                <div class="identifier" id="identifier"></div>
                <div class="series-div">
                    <ul class="series-ul">
                      <li class="seriesli">A 1</li>

                      <li class="seriesli">B 1</li>

                      <li class="seriesli">C 1</li>

                    </ul>
                  </div>
                <div id="line"></div>
                       <img src="https://stat.overdrive.in/wp-content/odgallery/2020/06/57263_2020_Mercedes_Benz_GLS.jpg" class="img-responsive firstcar-detail fullwidth-img">

        </div>

                   </div>

        <div class="col-md-5 col-xs-5 col-sm-5">

    <div>
        <img src="https://stat.overdrive.in/wp-content/odgallery/2020/06/57263_2020_Mercedes_Benz_GLS.jpg" class="img-responsive width70-img firstgraph pointer">
        <img src="https://stat.overdrive.in/wp-content/odgallery/2020/06/57263_2020_Mercedes_Benz_GLS.jpg" class="img-responsive width70-img zoomedgraph">
    </div>

        </div>

           </div>

        </div>
        </div></div>
        <div id="footer"><div class="row text-white footer">
        <div class="col-md-12 col-sm-12 col-xs-12">
            <div class="col-md-2 col-sm-2 col-xs-2"><a href="javascript:void(0);" class="hyperlink">Home</a>            </div>
            <div class="col-md-10 col-sm-10 col-xs-10 text-right"><a href="#" class="hyperlink">google.com</a></div>
        </div>
    </div>
    </div>

    </div>
<script>
$('.seriesli').click(function() {

  function adjustLine(from, to, line) {

    // Get actual position relative to viewport.
    // See https://stackoverflow.com/a/11396681/117030
    fromBCR = from.getBoundingClientRect();
    toBCR   = to.getBoundingClientRect();

    var fT = fromBCR.top + from.offsetHeight / 2;
    var tT = toBCR.top + to.offsetHeight / 2;

    // Don't add offsetWidth. This connects to the middle, not the left edge.
    var fL = fromBCR.left //+ from.offsetWidth / 2;
    var tL = toBCR.left + to.offsetWidth / 2;

    var CA = Math.abs(tT - fT);
    var CO = Math.abs(tL - fL);
    var H = Math.sqrt(CA * CA + CO * CO);
    var ANG = 180 / Math.PI * Math.acos(CA / H);

    if (tT > fT) {
      var top = (tT - fT) / 2 + fT;
    } else {
      var top = (fT - tT) / 2 + tT;
    }
    if (tL > fL) {
      var left = (tL - fL) / 2 + fL;
    } else {
      var left = (fL - tL) / 2 + tL;
    }

    if ((fT < tT && fL < tL) || (tT < fT && tL < fL) || (fT > tT && fL > tL) || (tT > fT && tL > fL)) {
      ANG *= -1;
    }
    top -= H / 2;

    line.style["-webkit-transform"] = 'rotate(' + ANG + 'deg)';
    line.style["-moz-transform"] = 'rotate(' + ANG + 'deg)';
    line.style["-ms-transform"] = 'rotate(' + ANG + 'deg)';
    line.style["-o-transform"] = 'rotate(' + ANG + 'deg)';
    line.style["-transform"] = 'rotate(' + ANG + 'deg)';
    line.style.top = top + 'px';
    line.style.left = left + 'px';
    line.style.height = H + 'px';
  }
  adjustLine(
    this, // Element that was clicked.
    document.getElementById('identifier'),
    document.getElementById('line')
  );
});

</script>
goqiplq2

goqiplq21#

正如注解中所建议的,必须将#line元素移动到文档根目录中(无论是开始还是结束,这都无关紧要,但如果在顶部添加,您还必须设置 z-index 设置为高于任何元素的值,否则将覆盖该值)
除此之外,您还必须考虑窗口的滚动位置,因此添加 window.scrollX.left 价值观和 window.scrollY.top 价值观

$('.seriesli').click(function() {

  function adjustLine(from, to, line) {

    // Get actual position relative to viewport.
    // See https://stackoverflow.com/a/11396681/117030
    fromBCR = from.getBoundingClientRect();
    toBCR = to.getBoundingClientRect();

    var fT = fromBCR.top + from.offsetHeight / 2 + window.scrollY;
    var tT = toBCR.top + to.offsetHeight / 2 + window.scrollY;

    // Don't add offsetWidth. This connects to the middle, not the left edge.
    var fL = fromBCR.left + window.scrollX //+ from.offsetWidth / 2;
    var tL = toBCR.left + to.offsetWidth / 2 + window.scrollX;

    var CA = Math.abs(tT - fT);
    var CO = Math.abs(tL - fL);
    var H = Math.sqrt(CA * CA + CO * CO);
    var ANG = 180 / Math.PI * Math.acos(CA / H);

    if (tT > fT) {
      var top = (tT - fT) / 2 + fT;
    } else {
      var top = (fT - tT) / 2 + tT;
    }
    if (tL > fL) {
      var left = (tL - fL) / 2 + fL;
    } else {
      var left = (fL - tL) / 2 + tL;
    }

    if ((fT < tT && fL < tL) || (tT < fT && tL < fL) || (fT > tT && fL > tL) || (tT > fT && tL > fL)) {
      ANG *= -1;
    }
    top -= H / 2;

    line.style["-webkit-transform"] = 'rotate(' + ANG + 'deg)';
    line.style["-moz-transform"] = 'rotate(' + ANG + 'deg)';
    line.style["-ms-transform"] = 'rotate(' + ANG + 'deg)';
    line.style["-o-transform"] = 'rotate(' + ANG + 'deg)';
    line.style["-transform"] = 'rotate(' + ANG + 'deg)';
    line.style.top = top + 'px';
    line.style.left = left + 'px';
    line.style.height = H + 'px';
  }
  adjustLine(
    this, // Element that was clicked.
    document.getElementById('div2'),
    document.getElementById('line')
  );
});
@import url('https://fonts.googleapis.com/css2?family=Ubuntu:wght@300;400;500;700&display=swap');
html,
body {
  font-family: 'Ubuntu', sans-serif;
  background-color: lightblue;
  color: #000;
}

# content {

  color: #787878;
}

.container-fluid-child {
  background-color: #fff;
  position: relative;
  padding: 5%;
}

.container-fluid-innerchild {
  background-color: #fff;
  position: relative;
  border-radius: 25px;
}

.text-white {
  color: #fff;
}

.car-image {
  width: 35%;
  max-width: 35%;
  border: 1px solid #000;
}

.step-one {
  width: 130px;
  height: 130px;
  background-color: #81a1b6;
  color: #fff;
  justify-content: center;
  align-items: center;
  display: flex;
  border-radius: 50%;
}

.sound-icon {
  width: 20px;
  float: left;
  margin-right: 10px;
}

.set-sound {
  position: absolute;
  top: 2.4em;
  width: 100%;
}

.intro-para {
  position: absolute;
  width: 35%;
  font-size: 1.2em;
}

.hyperlink {
  color: #fff;
  text-decoration: none;
  font-size: 1.3em;
}

.hyperlink:hover {
  color: #fff;
  font-weight: 900;
  text-decoration: none;
}

.hyperlink:focus {
  color: #fff;
  text-decoration: none;
}

.footer {
  padding: 1em;
}

.text-over-image {
  float: left;
  position: absolute;
  bottom: 23em;
  left: 5em;
}

.relative {
  position: relative;
}

.textonimage {
  position: absolute;
  max-width: 30%;
  top: 2%;
  font-weight: 600;
}

.ableft {
  left: 1em;
}

.abright {
  right: 1em;
}

.car {
  cursor: pointer;
}

.grey {
  color: grey;
  font-weight: 600;
  margin-left: 1.5em;
  max-width: 50%;
  position: relative;
  top: 1em;
}

.no-padding {
  padding: 0px;
}

.firstcar-detail {
  border-radius: 25px;
}

# hr {

  -moz-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  -webkit-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  transform: rotate(-45deg);
  top: 12%;
  left: 18%;
  height: 20%;
  background-color: #000;
  width: 1px;
  position: absolute;
}

# hrtext {

  position: absolute;
  bottom: 85%;
  left: 5%;
}

.series-ul li {
  list-style: none;
  color: grey;
  font-size: 1em;
  font-weight: 600;
  border: 2px solid grey;
  display: table;
  padding: 0.3em 0.1em;
  text-align: center;
  margin: 0.5em;
  cursor: pointer;
}

.series-div {
  position: absolute;
  left: 65%;
  top: 0em;
}

.identifier {
  width: 10px;
  height: 10px;
  background-color: red;
  position: absolute;
  right: 45%;
  top: 30%;
}

# line {

  position: absolute;
  width: 2px;
  margin-top: -1px;
  background-color: red;
}

.fullwidth-img {
  width: 100%;
}

.width70-img {
  width: 90%;
  margin: 0px auto;
  margin-top: 10%;
}

.margintop10 {
  margin-top: 10%;
}

.hide {
  display: none;
}

.pointer {
  cursor: pointer;
}

.bottom-text {
  position: absolute;
  bottom: 5%;
  left: 5%;
  max-width: 15%;
}

@media only screen and (max-width: 1024px) {
  .series-ul li {
    font-size: 1em;
    min-width: auto;
  }
  .grey {
    max-width: 100%;
    font-size: 1.5em;
    top: auto;
  }
  .header .text-right {
    text-align: center;
    font-size: 2em;
  }
  .set-sound {
    top: 4em;
  }
  .bottom-text {
    bottom: 0%;
    max-width: 100%;
  }
  .intro-para {
    position: relative;
    width: 100%;
    text-align: center;
  }
  .textonimage {
    bottom: 100%;
    top: auto;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container-fluid">

  <div id="header">
    <div class="row  header">
      <div class="col-md-12 col-sm-12 col-xs-12">
        <div class="col-md-8 col-sm-8 col-xs-8">
          <h1 class="text-right">Some dummy placeholder - Random text </h1>
        </div>
        <div class="col-md-4 col-sm-4 col-xs-4">
          <div class="set-sound">
            <img src="images/icons8-sound-50.png" class="img-responsive sound-icon hide">

            <p>Some dummy placeholder</p>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div id="content">
    <div class="container-fluid-innerchild">
      <div class="row">
        <div class="col-md-12 col-sm-12 col-xs-12">
          <div class="col-md-7 col-sm-7 col-xs-7 no-padding">
            <div id="greytext">
              <h2 class="grey">Some dummy placeholder - Random text</h2>
            </div>
            <br>
            <div class="relative">
              <div>
                <div id="hrtext">
                  <p>Some dummy placeholder
                  </p>
                </div>

                <div id="hr"></div>
              </div>
              <div class="identifier" id="div2"></div>
              <div class="series-div">
                <ul class="series-ul">
                  <li class="seriesli" id="div1">A 1</li>

                  <li class="seriesli">B 1</li>

                  <li class="seriesli">C 1</li>

                </ul>
              </div>
              <img src="https://stat.overdrive.in/wp-content/odgallery/2020/06/57263_2020_Mercedes_Benz_GLS.jpg" class="img-responsive firstcar-detail fullwidth-img">

            </div>

          </div>

          <div class="col-md-5 col-xs-5 col-sm-5">

            <div>
              <img src="https://stat.overdrive.in/wp-content/odgallery/2020/06/57263_2020_Mercedes_Benz_GLS.jpg" class="img-responsive width70-img firstgraph pointer">
              <img src="https://stat.overdrive.in/wp-content/odgallery/2020/06/57263_2020_Mercedes_Benz_GLS.jpg" class="img-responsive width70-img zoomedgraph">
            </div>

          </div>

        </div>

      </div>
    </div>
  </div>
  <div id="footer">
    <div class="row text-white footer">
      <div class="col-md-12 col-sm-12 col-xs-12">
        <div class="col-md-2 col-sm-2 col-xs-2"><a href="javascript:void(0);" class="hyperlink">Home</a> </div>
        <div class="col-md-10 col-sm-10 col-xs-10 text-right"><a href="#" class="hyperlink">google.com</a></div>
      </div>
    </div>
  </div>

</div>
<div id="line"></div>
uurv41yg

uurv41yg2#

当然,在我看来,这里存在着这么多的js努力。
为什么不直接使用css呢?
例如:
html

<ul class="series-ul">
  <li id="line1" class="active">A 1</li>
  <li id="line2">B 1</li>
  <li id="line3">C 1</li>
</ul>

css

.series-ul li {
  position: relative;
}

.series-ul li.active {
  background: red;
  color: white;
  border-color: red;
}

.series-ul li::after {
  position: absolute;
  content: " ";
  display: none;
  width: 150px;
  height: 5px;
  border-top: 1px solid red;
}

.series-ul li.active::after {
  display: block;
}

# line1::after {

  transform: rotate(-31deg);
  top: 46px;
  right: 16px;
  width: 120px;
}

# line2::after {

  transform: rotate(-15deg);
  top: 26px;
  right: 21px;
  width: 106px;
}

# line3::after {

  transform: rotate(8deg);
  top: 9px;
  right: 23px;
  width: 103px;
}

js

$(".series-ul li").click(function() {
    $(".series-ul li").removeClass("active");
    $(this).addClass("active");
});

演示:https://jsfiddle.net/caneroncel/fmq9p1lt/15/

相关问题