当前位置: 代码迷 >> JavaScript >> 将弹出框定位在元素中心
  详细解决方案

将弹出框定位在元素中心

热度:102   发布时间:2023-06-05 11:41:55.0

我正在使用SVG构建资源图。 当用户单击单个元素时,我想在该元素的中心放置一个弹出框。 但是,由于地图是通过CSS旋转的, 技术并不成功。

这是我的JavaScript:

Map.popup = function(e) {
    var rect = $(this);
    var offset = $(this).offset();

    var rectWidth = $(this).attr('width').replace(/[^-\d\.]/g, '');
    var rectHeight = $(this).attr('height').replace(/[^-\d\.]/g, '');

    var centerX = offset.left - rectWidth/2;
    var centerY = offset.top - rectHeight/2;

    $('.popup').css({
       'top' : centerY,
       'left' : centerX,
    });
}

这是标记:

    <div id="map">
    <svg width="1088px" height="1088px" xmlns="http://www.w3.org/2000/svg">
        <g transform="translate(288.0 32.0) rotate(45 256.0 512.0)">
            <rect id="0" x="8px" y="8px" width="51px" height="230px"></rect>
            <rect id="1" x="67px" y="8px" width="112px" height="38px"></rect>
            <rect id="2" x="187px" y="8px" width="144px" height="38px"></rect>
            <rect id="3" x="339px" y="8px" width="165px" height="38px"></rect>
            <rect id="4" x="67px" y="54px" width="112px" height="44px"></rect>
            <rect id="5" x="187px" y="54px" width="144px" height="75px"></rect>
            <rect id="6" x="339px" y="54px" width="35px" height="24px"></rect>
            <rect id="7" x="382px" y="54px" width="122px" height="51px"></rect>
            <rect id="8" x="339px" y="86px" width="35px" height="204px"></rect>
            <rect id="9" x="67px" y="106px" width="52px" height="132px"></rect>
            <rect id="10" x="127px" y="106px" width="52px" height="132px"></rect>
            <rect id="11" x="382px" y="113px" width="122px" height="78px" class=""></rect>
            <rect id="12" x="187px" y="137px" width="144px" height="70px"></rect>
            <rect id="13" x="382px" y="199px" width="122px" height="91px"></rect>
            <rect id="14" x="187px" y="215px" width="144px" height="65px"></rect>
            <rect id="15" x="8px" y="246px" width="171px" height="58px" class="selected"></rect>
            <rect id="16" x="187px" y="288px" width="144px" height="70px"></rect>
            <rect id="17" x="339px" y="298px" width="165px" height="60px" class=""></rect>
            <rect id="18" x="8px" y="312px" width="171px" height="50px"></rect>
            <rect id="19" x="187px" y="366px" width="144px" height="74px"></rect>
            <rect id="20" x="339px" y="366px" width="165px" height="28px"></rect>
            <rect id="21" x="8px" y="370px" width="171px" height="58px"></rect>
            <rect id="22" x="339px" y="402px" width="165px" height="38px"></rect>
            <rect id="23" x="8px" y="436px" width="171px" height="70px"></rect>
            <rect id="24" x="187px" y="448px" width="87px" height="58px"></rect>
            <rect id="25" x="282px" y="448px" width="49px" height="58px"></rect>
            <rect id="26" x="339px" y="448px" width="165px" height="58px"></rect>
            <rect id="27" x="8px" y="514px" width="171px" height="67px"></rect>
            <rect id="28" x="187px" y="514px" width="87px" height="67px"></rect>
            <rect id="29" x="282px" y="514px" width="49px" height="67px"></rect>
            <rect id="30" x="339px" y="514px" width="19px" height="44px"></rect>
            <rect id="31" x="366px" y="514px" width="46px" height="44px"></rect>
            <rect id="32" x="420px" y="514px" width="84px" height="22px"></rect>
            <rect id="33" x="420px" y="544px" width="84px" height="69px"></rect>
            <rect id="34" x="339px" y="566px" width="73px" height="53px"></rect>
            <rect id="35" x="8px" y="589px" width="171px" height="55px"></rect>
            <rect id="36" x="187px" y="589px" width="24px" height="36px"></rect>
            <rect id="37" x="219px" y="589px" width="112px" height="36px"></rect>
            <rect id="38" x="420px" y="621px" width="84px" height="71px"></rect>
            <rect id="39" x="339px" y="627px" width="73px" height="99px"></rect>
            <rect id="40" x="187px" y="633px" width="24px" height="105px"></rect>
            <rect id="41" x="219px" y="633px" width="112px" height="105px"></rect>
            <rect id="42" x="8px" y="652px" width="103px" height="36px"></rect>
            <rect id="43" x="119px" y="652px" width="60px" height="179px"></rect>
            <rect id="44" x="8px" y="696px" width="103px" height="49px"></rect>
            <rect id="45" x="420px" y="700px" width="84px" height="26px"></rect>
            <rect id="46" x="339px" y="734px" width="165px" height="46px"></rect>
            <rect id="47" x="187px" y="746px" width="24px" height="85px"></rect>
            <rect id="48" x="219px" y="746px" width="112px" height="34px"></rect>
            <rect id="49" x="8px" y="753px" width="103px" height="122px"></rect>
            <rect id="50" x="219px" y="788px" width="112px" height="43px"></rect>
            <rect id="51" x="339px" y="788px" width="165px" height="43px"></rect>
            <rect id="52" x="119px" y="839px" width="92px" height="177px"></rect>
            <rect id="53" x="219px" y="839px" width="46px" height="177px"></rect>
            <rect id="54" x="273px" y="839px" width="58px" height="53px"></rect>
            <rect id="55" x="339px" y="839px" width="58px" height="53px"></rect>
            <rect id="56" x="405px" y="839px" width="99px" height="53px"></rect>
            <rect id="57" x="8px" y="883px" width="103px" height="39px"></rect>
            <rect id="58" x="273px" y="900px" width="124px" height="116px"></rect>
            <rect id="59" x="405px" y="900px" width="19px" height="116px"></rect>
            <rect id="60" x="432px" y="900px" width="72px" height="116px"></rect>
            <rect id="61" x="8px" y="930px" width="103px" height="86px"></rect>
        </g>
    </svg>
</div>

您可以在以下位置查看地图的版本(及其定位不完善): : 。

关于如何更好地定位每个中心的想法?

首先,需要使用getBoundingClientRect()来获取自单击的SVG元素旋转以来所包围的边界区域的实际宽度。 然后,您需要将其一半添加到偏移量中,而不是减去它,这将使弹出窗口的左上角位于SVG clicked元素的中心。

如果您还从centerX计算中减去了250px(弹出元素的宽度),则弹出箭头点(位于右上角)应很好地居中于所单击元素的中间。

新代码:

Map.popup = function(e) {
 var rect = $(this);
 var offset = $(this).offset();

 var rectWidth = $(this)[0].getBoundingClientRect().width;
 var rectHeight = $(this)[0].getBoundingClientRect().height;

 var centerX = offset.left + rectWidth/2 - 250;
 var centerY = offset.top + rectHeight/2;

 $('.popup').css({
   'top' : centerY,
   'left' : centerX,
 });
}

正如@sjm所指出的,您可以使用getBoundingCliendRect()来获取“真实”的高度/宽度,但不适用于$(this)

Map.popup = function(e) {    
  var rect          = $(this);
      offset        = $(this).offset(),
      canvas        = document.getElementById(rect.prop('id')),
      rectWidth     = canvas.getBoundingClientRect().width,
      rectHeight    = canvas.getBoundingClientRect().height,
      popoverWidth  = 250,
      popoverHeight = $('.popup').height(),
      centerX       = offset.left - popoverWidth + rectWidth/2,
      centerY       = offset.top + rectHeight/2;

  $('.popup').css({
     'top' : centerY,
     'left' : centerX,
  });
}

而且您的centerXcenterY是错误的,我已更正了它们。

干杯!

  相关解决方案