在 2 个 div 之间连接一条线

Posted

技术标签:

【中文标题】在 2 个 div 之间连接一条线【英文标题】:Connect a line between 2 divs 【发布时间】:2021-12-14 19:52:28 【问题描述】:

我正在尝试使用divs 和每两个divs 之间的连接线进行类似网络的设计,但是当我将svgline 标签与下面的JS 函数一起使用时,控制台显示错误这么说

位置不是函数。

我的代码有什么问题?我该如何解决,或者有其他方法可以在两个divs 之间画线吗? ** 问题已解决,但现在我尝试使用循环和数组,因为如果我手动连接所有 div,它将永远需要。所以我写了下面的代码,但知道它再次显示相同的错误。我试图将数组的每个元素放在一个变量中,但它也不起作用。 **

代码如下:

```
  $(function() 
var orgs = document.getElementsByClassName('org'),
    lines = document.getElementsByClassName('con-line'),
    org1,
    org2,
    line,
    pos1,
    pos2,
    count = 0;

for (let i = 0; i < orgs.length; i++) 
    
    org1 = orgs[i];

    for (let j = 0; j < orgs.length; j++) 

        org2 = orgs[j];
        line = lines[count];


        if (j != i)
        
            pos1 = org1.position();
            pos2 = org2.position();

            line
                .attr('x1', pos1.left)
                .attr('y1', pos1.top)
                .attr('x2', pos2.left)
                .attr('y2', pos2.top)
                .attr('stroke', 'red')
                .attr('stroke-width', 2);

                count++;
        
      

      
  );
```

【问题讨论】:

【参考方案1】:

jQuery

    尝试将您的代码包装成“document ready”结构。这将确保在加载 jQuery 之后执行代码。

    定义strokestroke-width 属性以使线条可见。

$(function() 
  var line1= $('#line1');
  var div1 = $('#org1');
  var div2 = $('#org2');

  var l1pos1 = div1.position();
  var l1pos2 = div2.position();

  line1
    .attr('x1', l1pos1.left)
    .attr('y1', l1pos1.top)
    .attr('x2', l1pos2.left)
    .attr('y2', l1pos2.top)
    .attr('stroke', 'red')
    .attr('stroke-width', 10);
);
.con
    margin-top: 50px;


.con-title
    width: 100%;
    text-align: center;
    color: #4E4E50;
    font-size: 40px;
    font-weight: bold;


.org-map
    position: relative;
    width: 300px;
    height: 300px;
    margin: 40px auto 0 auto;


.org
    position: absolute;


.org .org-box
    position: relative;
    bottom: 0px;
    width: 15px;
    height: 15px;
    border-radius: 20px;
    background: #4E4E50;
    transition: 0.6s;


#org1
    transform: translate(-50%, 0%);
    bottom: 80%;
    left: 50%;


#org2
    transform: translate(-50%, 0%);
    bottom: 65%;
    left: 20%;


#org3
    transform: translate(-50%, 0%);
    bottom: 35%;
    left: 20%;


#org4
    transform: translate(-50%, 0%);
    bottom: 50%;
    left: 50%;


#org5
    transform: translate(-50%, 0%);
    bottom: 65%;
    left: 80%;


#org6
    transform: translate(-50%, 0%);
    bottom: 35%;
    left: 80%;


#org7
    transform: translate(-50%, 0%);
    bottom: 20%;
    left: 50%;


.org:hover .org-box
    background: #C3073F;
    animation: org 1s;
    animation-fill-mode: forwards;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="con">
  <div class="con-title">Contributions</div>
  <div class="org-map">
    <div class="org" id="org1">
        <div class="org-box">
            <img src="" >
        </div>
    </div>
    <div class="org" id="org2">
        <div class="org-box">
            <img src="" >
        </div>
    </div>
    <div class="org" id="org3">
        <div class="org-box">
            <img src="" >
        </div>
    </div>
    <div class="org" id="org4">
        <div class="org-box">
            <img src="" >
        </div>
    </div>
    <div class="org" id="org5">
        <div class="org-box">
            <img src="" >
        </div>
    </div>
    <div class="org" id="org6">
        <div class="org-box">
            <img src="" >
        </div>
    </div>
    <div class="org" id="org7">
        <div class="org-box">
            <img src="" >
        </div>
    </div>
    <svg  >
        <line id="line1"/>
        <line id="line2"/>
    </svg>
  </div>
</div>

javascript

    您可以使用Element.getBoundingClientRect() 方法获取有关div 块的更多信息。

    在这种情况下,在计算中,需要考虑 SVG 元素本身的位置。为此,我们从点的绝对坐标中减去 SVG 左上角的对应坐标。

这是一个没有 jQuery 的 JavaScript 代码示例:

let line1 = document.getElementById('line1');

let svgRect = document.getElementById('lines').getBoundingClientRect();

let rect1 = document.getElementById('org1').getBoundingClientRect();
let rect2 = document.getElementById('org2').getBoundingClientRect();

let dot1x = (rect1.left + rect1.right) / 2;
let dot1y = (rect1.top + rect1.bottom) / 2;

let dot2x = (rect2.left + rect2.right) / 2;
let dot2y = (rect2.top + rect2.bottom) / 2;

setAttributes(line1, 
  'x1': dot1x - svgRect.left,
  'y1': dot1y - svgRect.top,
  'x2': dot2x - svgRect.left,
  'y2': dot2y - svgRect.top,
  'stroke': 'red',
  'stroke-width': 4,
);

// helper function from https://***.com/a/12274782/6263942
function setAttributes(el, attrs) 
  for(var key in attrs) 
    el.setAttribute(key, attrs[key]);
  
.con 
  margin-top: 50px;


.con-title 
  width: 100%;
  text-align: center;
  color: #4E4E50;
  font-size: 40px;
  font-weight: bold;


.org-map 
  position: relative;
  width: 300px;
  height: 300px;
  margin: 40px auto 0 auto;


.org 
  position: absolute;


.org .org-box 
  position: relative;
  bottom: 0px;
  width: 15px;
  height: 15px;
  border-radius: 20px;
  background: #4E4E50;
  transition: 0.6s;


#org1 
  transform: translate(-50%, 0%);
  bottom: 80%;
  left: 50%;


#org2 
  transform: translate(-50%, 0%);
  bottom: 65%;
  left: 20%;


#org3 
  transform: translate(-50%, 0%);
  bottom: 35%;
  left: 20%;


#org4 
  transform: translate(-50%, 0%);
  bottom: 50%;
  left: 50%;


#org5 
  transform: translate(-50%, 0%);
  bottom: 65%;
  left: 80%;


#org6 
  transform: translate(-50%, 0%);
  bottom: 35%;
  left: 80%;


#org7 
  transform: translate(-50%, 0%);
  bottom: 20%;
  left: 50%;


.org:hover .org-box 
  background: #C3073F;
  animation: org 1s;
  animation-fill-mode: forwards;
<div class="con">
  <div class="con-title">Contributions</div>
  <div class="org-map">
    <div class="org" id="org1">
      <div class="org-box">
        <img src="" >
      </div>
    </div>
    <div class="org" id="org2">
      <div class="org-box">
        <img src="" >
      </div>
    </div>
    <div class="org" id="org3">
      <div class="org-box">
        <img src="" >
      </div>
    </div>
    <div class="org" id="org4">
      <div class="org-box">
        <img src="" >
      </div>
    </div>
    <div class="org" id="org5">
      <div class="org-box">
        <img src="" >
      </div>
    </div>
    <div class="org" id="org6">
      <div class="org-box">
        <img src="" >
      </div>
    </div>
    <div class="org" id="org7">
      <div class="org-box">
        <img src="" >
      </div>
    </div>
    <svg   id="lines">
        <line id="line1"/>
        <line id="line2"/>
    </svg>
  </div>
</div>

【讨论】:

@ahmed-gouda 我已经添加了一个没有 jQuery 的更准确的解决方案

以上是关于在 2 个 div 之间连接一条线的主要内容,如果未能解决你的问题,请参考以下文章

如何在Matlab中永久地在图像的两个坐标之间画一条线? [重复]

在绘制的点之间绘制一条线

SwiftUI:在列表中的两个视图之间画一条线/如何确定视图的中心位置?

openGL着色器:两个对象和一条线来连接它们

用一条线连接箱线图(ggplot2)

了解3dmax多边形建模连接命令