我正在尝试使用 element.getBoundingClientRect() 在单击的元素和“#identifier”之间画一条线。 element.getBoundingClientRect() 由于页面上的一些其他元素是相对定位的,因此无法获取元素的实际坐标。当我尝试注释掉 '#header' 和 '#greytext' 元素时,该行按预期显示。页面上的其他元素会影响 getBoundingClientRect() 坐标吗?
这是我的代码:
未对齐的行:https://jsfiddle.net/SampathPerOxide/jdyoz3r4/34/
注释掉“#header”和“#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>
答案 0 :(得分:0)
正如评论中所建议的,您的 #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>
答案 1 :(得分:-1)
这里有很多 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");
});