单击时从一个元素到多个元素绘制一条线

Sam*_*ath 6 html javascript css jquery

我正在尝试从元素 [.identifier] 到单击的元素 [ A, B, C series ] 画一条线。我能够显示这条线,但在另一个方向上,不知道为什么它在这样一个方向上显示。这是我的小提琴:https : //jsfiddle.net/SampathPerOxide/u2afymxs/11/ 有人可以帮我在“.identifier”和相应的系列元素之间显示一条线吗?

单击 A 系列的预期结果: 在此处输入图片说明 点击 B 系列: 在此处输入图片说明

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

  function adjustLine(from, to, line) {

    var fT = from.offsetTop + from.offsetHeight / 2;
    var tT = to.offsetTop + to.offsetHeight / 2;
    var fL = from.offsetLeft + from.offsetWidth / 2;
    var tL = to.offsetLeft + 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(
    document.getElementById('div1'),
    document.getElementById('div2'),
    document.getElementById('line')
  );
});
Run Code Online (Sandbox Code Playgroud)
.identifier {
  width: 10px;
  height: 10px;
  background-color: red;
  position: absolute;
  right: 45%;
  top: 50%;
}

.series-div {
  position: absolute;
  right: 5%;
  bottom: 30%;
}

.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;
}

#line {
  position: absolute;
  width: 2px;
  margin-top: -1px;
  background-color: red;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="position;relative;">
  <div class="identifier" id="div2"></div>
  <div class="series-div">
    <ul class="series-ul">
      <li class="seriesli" id="div1">A series</li>

      <li class="seriesli">B series</li>
  
      <li class="seriesli">C series</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" style="width: 100%;">

</div>
Run Code Online (Sandbox Code Playgroud)

Lef*_*ium 7

我修好了你的小提琴:https : //jsfiddle.net/c4ju6a0p/

代码更改:

// Get actual position relative to viewport.
// See /sf/answers/797767701/
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;
Run Code Online (Sandbox Code Playgroud)
  • 问题是由于relative定位,计算线的位置不正确。relative注释掉 CSS时可以更清楚地看到这一点:https : //jsfiddle.net/vust5nxf/
  • 另外,offsetWidth如果您希望该线到达左边缘,请不要添加。

更新:没有注意到代码片段......也在那里应用了更改。我还做了一个改动:

  • 您需要将点击的元素传递给adjustLine(),否则当前每次都会在相同的两个元素之间绘制线条,因为这些元素是用 id 硬编码的。
  • 作为样式说明:我会将函数的定义移到adjustLine()点击处理程序之外。这将使代码更易于阅读,并且该函数只会创建一次,而不是每次处理一次点击。
adjustLine(
  this, // Element that was clicked.
  document.getElementById('div2'),
  document.getElementById('line')
);
Run Code Online (Sandbox Code Playgroud)

// 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;
Run Code Online (Sandbox Code Playgroud)
adjustLine(
  this, // Element that was clicked.
  document.getElementById('div2'),
  document.getElementById('line')
);
Run Code Online (Sandbox Code Playgroud)
$('.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('div2'),
    document.getElementById('line')
  );
});
Run Code Online (Sandbox Code Playgroud)