我如何重新定位悬停在悬停的卡片

发布于 2025-02-12 04:00:05 字数 1166 浏览 3 评论 0原文

我有一张带有卡片的地图,显示何时将热点悬停。非常感谢在这个论坛上的帮助。我唯一的问题是在浏览器右边缘附近的热点右侧的卡片显示。 它是由CSS和JavaScript设置的,后者什至不是新手。

我尝试了其他CSS职位,但无效。我假设JavaScript中的某些内容需要更改?

这是网页。超过35或36的悬停说明了问题。

这是CSS:

#card {
    position: relative;
    left: 30px;
    width: 300px;
    height: 150px;
    display: none;
    border: none;
    background: #ffd;
    pointer-events: none;
}

这是JavaScript:

let paths = document.querySelectorAll("path");
paths.forEach((p) => {
    p.addEventListener("mouseleave", (evt) => {
        card.style.display = "none";  
    });
    p.addEventListener("mousemove", (evt) => {
    let pos = oMousePos(svg, evt);
    let text = p.dataset.text;

    card.style.display = "block";
    card.style.top = pos.y + "px";
    card.style.left = pos.x + "px";
    card.innerHTML = text;
    });

});

function oMousePos(element, evt) {
    let ClientRect = element.getBoundingClientRect();
    return {
    //objeto
    x: Math.round(evt.clientX - ClientRect.left),
    y: Math.round(evt.clientY - ClientRect.top)
    };
}

I have a map with cards that show when a hotspot is hovered over. Works great thanks to help on this forum. The only problem I am having is the card shows to the right of the hotspot therefor gets cut off when near the right edge of the browser.
It is set up with css and javascript, the latter of which I am not even a novice.

I tried other css positions but didnt work. I'm assuming something in the javascript needs to be changed??

This is the webpage. Hovering over number 35 or 36 illustrates the problem.

This is the CSS:

#card {
    position: relative;
    left: 30px;
    width: 300px;
    height: 150px;
    display: none;
    border: none;
    background: #ffd;
    pointer-events: none;
}

This is the Javascript:

let paths = document.querySelectorAll("path");
paths.forEach((p) => {
    p.addEventListener("mouseleave", (evt) => {
        card.style.display = "none";  
    });
    p.addEventListener("mousemove", (evt) => {
    let pos = oMousePos(svg, evt);
    let text = p.dataset.text;

    card.style.display = "block";
    card.style.top = pos.y + "px";
    card.style.left = pos.x + "px";
    card.innerHTML = text;
    });

});

function oMousePos(element, evt) {
    let ClientRect = element.getBoundingClientRect();
    return {
    //objeto
    x: Math.round(evt.clientX - ClientRect.left),
    y: Math.round(evt.clientY - ClientRect.top)
    };
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一抹淡然 2025-02-19 04:00:05

您需要检查当前光标X/Y位置 +卡/弹出宽度是否超​​过您的SVG边界:

function oMousePos(element, evt) {
  let ClientRect = element.getBoundingClientRect();
  let currentX = Math.round(evt.clientX - ClientRect.left);
  let currentY = Math.round(evt.clientY - ClientRect.top);

  //close to right
  if (evt.clientX + cardWidth >= ClientRect.right) {
    currentX = Math.round(evt.clientX - ClientRect.left - cardWidth);
  }
  //close to bottom
  if (evt.clientY + cardHeight >= ClientRect.bottom) {
    currentY = Math.round(evt.clientY - ClientRect.top - cardHeight);
  }
  return {
    x: currentX,
    y: currentY
  };
}

如果光标位置靠近右边(evt.clientx + cardWidth),则可以添加负面偏移300(弹出窗口的宽度)。垂直溢出的相同过程。

简化的示例

    let paths = document.querySelectorAll("path");
    let cardWidth = card.getBoundingClientRect().width;
    let cardHeight = card.getBoundingClientRect().height;

    paths.forEach((p) => {
      p.addEventListener("mouseleave", (evt) => {
        card.style.visibility = "hidden";
      });
      p.addEventListener("mousemove", (evt) => {
        let pos = oMousePos(svg, evt);
        let text = p.dataset.text;
        card.style.visibility = "visible";
        card.style.top = pos.y + "px";
        card.style.left = pos.x + "px";
        card.innerHTML = text;
      });
    });


    function oMousePos(element, evt) {
      let ClientRect = element.getBoundingClientRect();
      let currentX = Math.round(evt.clientX - ClientRect.left);
      let currentY = Math.round(evt.clientY - ClientRect.top);

      //close to right
      if (evt.clientX + cardWidth >= ClientRect.right) {
        currentX = Math.round(evt.clientX - ClientRect.left - cardWidth);
      }
      //close to bottom
      if (evt.clientY + cardHeight>= ClientRect.bottom) {
        currentY = Math.round(evt.clientY - ClientRect.top - cardHeight);
      }
      return {
        x: currentX,
        y: currentY
      };
    }
 #card {
      position: absolute;
      width: 33%;
      height: 10vmin;
      /* display: none;*/
      visibility: hidden;
      border: none;
      background: #ffd;
      pointer-events: none;
    }

    svg{
      width:90%;
    }

    svg path {
      fill: red !important;
      opacity: 0.5 !important;
    }
<svg id="svg" viewBox="0 0 2250 1800" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"><g data-groupmode="layer" data-label="Image" id="g448">
  <rect x="0" y="0" width="100%" height="100%" fill="#ccc"></rect>
  <a xlink:href="http://travelalberta.com/"><path d="m1922 187-8-68 132 12 29 20 4 36-99 12z" id="path1336" data-text="<h4>Bobs Boquets</h4><h5>23rd street NW Flower Ave</h5><h6>Next to Widget World1</h6>"/></a><path d="m2088 420-22-18 14-22 70-5 26-31 25 4-7 21 24 14 3 30-17 11-25 5-57 10-22-6z" id="path1338" data-text="<h4>Bobs Boquets</h4><h5>23rd street NW Flower Ave</h5><h6>Next to Widget World2</h6>"/><path d="m1841 306-165-70 4-47 151 75z" id="path1334" data-text="<h4>Bobs Boquets</h4><h5>23rd street NW Flower Ave</h5><h6>Next to Widget World3</h6>"/><path d="M2111 1445s45 0 48-2c4-2 30-31 30-31l5-31-37-33-49 2-27 64v38z" id="path2293"/><path d="m1600 1658 41 5 60-41v-31l-46-36-56-4-21 35z" id="path2295"/><path d="m1112 1314 55-122 83 104 34 101-9 22-28 5-56-31z" id="path1392"/><path d="m1742 1447 18-24 116 27-8 18-29 14-31 5-25-5z" id="path1046"/><path d="m2174 577-37-1-87-67 23-26 142 42-1 21z" id="path1346"/><path d="m1700 1295-74-21-1-30 71 20z" id="path1005"/><path d="m1999 1184 2 30-37 1-1-30z" id="path1001"/><path d="M2040 1179h-42l-2-37 41-1z" id="path999"/><path d="m1838 1219 29 20-2 19-38 10-25-35 1-18 12-14 15-2z" id="path1003"/><path d="M1694 1240v-22l31-16h22l16 39v25h-48z" id="path1009"/><path d="m1753 1225-2-37 22-23 14 14-2 16 14 14-1 25-45-1z" id="path1007"/><path d="M1681 1209v-35h27l-3-8 6-10h13l7 7v10l5 1 6 11v15l-19-1-32 18v6h-2z" id="path1015"/><path d="M1734 1169v-19l9-17 10-4 13 6 3 13h7l24 17 2 21h-12v-12l-19-15-24 28z" id="path1011"/><path d="M1664 1177v-26l12-6-2-10 6-11 17 1 5 11 10-4 24 6-8 18-6-4-13 1-6 9 2 10h-25l1 10z" id="path1013"/><path d="m1592 1119 11 12v9l58 13 2 29-14 17-63-19-71-9-3-29 10-11 51 3 5-10z" id="path997"/><path d="m1696 1106-55 2-7-49 61-1z" id="path995"/><path d="m1517 1084 2-16 22-18 14-2 14 8 22 21-1 17-51 17z" id="path993"/><path d="M1450 1139c-2-8-19-39-19-39l1-17 39-4 15 25 14 8v28l-46 6z" id="path991"/><path d="m1388 1169-28-55v-13l16-24 34-3 35 60v22z" id="path989"/><path d="m1125 1112-4-23 38-32 18 2 48 38 2 20-52 16z" id="path987"/><path d="m1196 964-4-15 24-29 10-4 11 6 16 23 17 17 1 29-48 12z" id="path374"/><path d="M1398 931v-33l25-27 13-5 12 7 22 44-3 39-45 4z" id="path376"/><path d="m719 767-2-41 53-33 44 36v43l-47 40z" id="path1324"/><path d="M1975 644c-102-7-143-28-144-43 0-15 23-81 123-73 100 9 154 58 149 75-4 17-40 52-128 41z" id="path1344"/><path d="m1728 509 73 24 6 15-31 86-15 1-48-29-16-41 14-42z" id="path1342"/><path d="m1813 496-87 3-32-24-28-2-30-15 33-32 82-19 51 13z" id="path1340"/><path d="m1078 602 122-14 18-45 24 18s22 49-3 73c-24 24-82 40-138 28-56-13-23-60-23-60z" id="path4202"/><path d="m1043 575-3-32 81-56 75 42 4 44-42 6-7 14h-25l-25-7-28 1z" id="path4200"/><path d="m412 661 101-64 8-34 27-11 16 16 38-27 31 49-187 138z" id="path1322"/><path d="M474 529c-43-40-79-84-35-101s146-22 158 15c13 36-8 68-40 80-33 12-62 29-83 6z" id="path1320"/><path d="m1605 351-18-51-1-24 44-17 21-3 56 44 1 44z" id="path1332"/><path d="m1434 230-80 6-29-26v-45l32-18 33-1 40 43z" id="path1330"/><path d="m529 102-2-43 8-26 36-21 29 18 17 25v53l-46 6z" id="path1328"/><path d="m1201 1722-4-49-1-30 23-28 57 34 38 19-6 62-45 36z" id="path1390"/><path d="m1095 1622-108-84-4-41 30-27 22-3 102 62 11 27v31z" id="path1388"/><path d="m691 1706-4-21 22-10-3-33 31-7 66 26 17 22-1 35-52 46-43-41-10 9z" id="path1386"/><path d="m690 1432-1-26 25-23 11-5 31 17 11 13-2 27-19 13-36 1z" id="path1382"/><path d="m710 1372-42 17-41-83-4-28 24-11 26 9 30 44z" id="path1380"/><path d="m694 1290-50-32 20-99 12-15 98 52 13 82-5 21z" id="path1384"/><path d="m451 1290-4-21 57-55 43 23 1 30-25 28-19-11-19 26z" id="path1374"/><path d="m408 1209 13-6 2-12 31 3 23 20-1 30-31 27-36-21z" id="path1372"/><path d="m628 1188-65-41-4-24 20-28 31 15 45 29 7 27z" id="path1378"/><path d="m510 1216-5-39 21-14 2-22 18-4 66 45 6 32-45 36z" id="path1376"/><path d="m425 1173-4-32 20-27 17-11 30 32-5 34-28 28z" id="path1370"/><path d="m315 1122-2-41 14-18 18-1 28 24 1 30-7 25-31 9z" id="path1368"/><path d="m327 1016-21 17-13-12-10-31 10-26 26-5 13 40z" id="path1364"/><path d="m273 1049-27-4-11-10 18-27 21-12 20 22 4 21z" id="path1366"/><path d="m116 1085-29-26 4-20 168-62 12 8-3 10z" id="path1352"/><path d="m269 967-195 76-29-24 3-17 95-23 8-16 17-10 12 5 68-11 19 4z" id="path1348"/><path d="m240 921 31-12 15 10v27l-17 7-28-17z" id="path1360"/><path d="m288 936 13-17 17-9 10-14h13l6 11 15 29v6l-62 17-12-20z" id="path1362"/><path d="m290 872 48-43 46 25-9 34-67 2z" id="path1358"/><path d="m258 913-17-21-3-26 6-24 21-2 23 28-1 25z" id="path1356"/><path d="m203 938-31-21-2-50 30-8 18 8 22 26-2 22z" id="path1354"/></g></svg>
  <div id="card"></div>

You need to check if the current cursor x/y position + card/popup width exceeds your svg's boundaries:

function oMousePos(element, evt) {
  let ClientRect = element.getBoundingClientRect();
  let currentX = Math.round(evt.clientX - ClientRect.left);
  let currentY = Math.round(evt.clientY - ClientRect.top);

  //close to right
  if (evt.clientX + cardWidth >= ClientRect.right) {
    currentX = Math.round(evt.clientX - ClientRect.left - cardWidth);
  }
  //close to bottom
  if (evt.clientY + cardHeight >= ClientRect.bottom) {
    currentY = Math.round(evt.clientY - ClientRect.top - cardHeight);
  }
  return {
    x: currentX,
    y: currentY
  };
}

If the cursor position is close to the right (evt.clientX + cardWidth) you can add a negative offset of 300 (your popup's width). Same procedure for vertical overflow.

Simplified example

    let paths = document.querySelectorAll("path");
    let cardWidth = card.getBoundingClientRect().width;
    let cardHeight = card.getBoundingClientRect().height;

    paths.forEach((p) => {
      p.addEventListener("mouseleave", (evt) => {
        card.style.visibility = "hidden";
      });
      p.addEventListener("mousemove", (evt) => {
        let pos = oMousePos(svg, evt);
        let text = p.dataset.text;
        card.style.visibility = "visible";
        card.style.top = pos.y + "px";
        card.style.left = pos.x + "px";
        card.innerHTML = text;
      });
    });


    function oMousePos(element, evt) {
      let ClientRect = element.getBoundingClientRect();
      let currentX = Math.round(evt.clientX - ClientRect.left);
      let currentY = Math.round(evt.clientY - ClientRect.top);

      //close to right
      if (evt.clientX + cardWidth >= ClientRect.right) {
        currentX = Math.round(evt.clientX - ClientRect.left - cardWidth);
      }
      //close to bottom
      if (evt.clientY + cardHeight>= ClientRect.bottom) {
        currentY = Math.round(evt.clientY - ClientRect.top - cardHeight);
      }
      return {
        x: currentX,
        y: currentY
      };
    }
 #card {
      position: absolute;
      width: 33%;
      height: 10vmin;
      /* display: none;*/
      visibility: hidden;
      border: none;
      background: #ffd;
      pointer-events: none;
    }

    svg{
      width:90%;
    }

    svg path {
      fill: red !important;
      opacity: 0.5 !important;
    }
<svg id="svg" viewBox="0 0 2250 1800" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"><g data-groupmode="layer" data-label="Image" id="g448">
  <rect x="0" y="0" width="100%" height="100%" fill="#ccc"></rect>
  <a xlink:href="http://travelalberta.com/"><path d="m1922 187-8-68 132 12 29 20 4 36-99 12z" id="path1336" data-text="<h4>Bobs Boquets</h4><h5>23rd street NW Flower Ave</h5><h6>Next to Widget World1</h6>"/></a><path d="m2088 420-22-18 14-22 70-5 26-31 25 4-7 21 24 14 3 30-17 11-25 5-57 10-22-6z" id="path1338" data-text="<h4>Bobs Boquets</h4><h5>23rd street NW Flower Ave</h5><h6>Next to Widget World2</h6>"/><path d="m1841 306-165-70 4-47 151 75z" id="path1334" data-text="<h4>Bobs Boquets</h4><h5>23rd street NW Flower Ave</h5><h6>Next to Widget World3</h6>"/><path d="M2111 1445s45 0 48-2c4-2 30-31 30-31l5-31-37-33-49 2-27 64v38z" id="path2293"/><path d="m1600 1658 41 5 60-41v-31l-46-36-56-4-21 35z" id="path2295"/><path d="m1112 1314 55-122 83 104 34 101-9 22-28 5-56-31z" id="path1392"/><path d="m1742 1447 18-24 116 27-8 18-29 14-31 5-25-5z" id="path1046"/><path d="m2174 577-37-1-87-67 23-26 142 42-1 21z" id="path1346"/><path d="m1700 1295-74-21-1-30 71 20z" id="path1005"/><path d="m1999 1184 2 30-37 1-1-30z" id="path1001"/><path d="M2040 1179h-42l-2-37 41-1z" id="path999"/><path d="m1838 1219 29 20-2 19-38 10-25-35 1-18 12-14 15-2z" id="path1003"/><path d="M1694 1240v-22l31-16h22l16 39v25h-48z" id="path1009"/><path d="m1753 1225-2-37 22-23 14 14-2 16 14 14-1 25-45-1z" id="path1007"/><path d="M1681 1209v-35h27l-3-8 6-10h13l7 7v10l5 1 6 11v15l-19-1-32 18v6h-2z" id="path1015"/><path d="M1734 1169v-19l9-17 10-4 13 6 3 13h7l24 17 2 21h-12v-12l-19-15-24 28z" id="path1011"/><path d="M1664 1177v-26l12-6-2-10 6-11 17 1 5 11 10-4 24 6-8 18-6-4-13 1-6 9 2 10h-25l1 10z" id="path1013"/><path d="m1592 1119 11 12v9l58 13 2 29-14 17-63-19-71-9-3-29 10-11 51 3 5-10z" id="path997"/><path d="m1696 1106-55 2-7-49 61-1z" id="path995"/><path d="m1517 1084 2-16 22-18 14-2 14 8 22 21-1 17-51 17z" id="path993"/><path d="M1450 1139c-2-8-19-39-19-39l1-17 39-4 15 25 14 8v28l-46 6z" id="path991"/><path d="m1388 1169-28-55v-13l16-24 34-3 35 60v22z" id="path989"/><path d="m1125 1112-4-23 38-32 18 2 48 38 2 20-52 16z" id="path987"/><path d="m1196 964-4-15 24-29 10-4 11 6 16 23 17 17 1 29-48 12z" id="path374"/><path d="M1398 931v-33l25-27 13-5 12 7 22 44-3 39-45 4z" id="path376"/><path d="m719 767-2-41 53-33 44 36v43l-47 40z" id="path1324"/><path d="M1975 644c-102-7-143-28-144-43 0-15 23-81 123-73 100 9 154 58 149 75-4 17-40 52-128 41z" id="path1344"/><path d="m1728 509 73 24 6 15-31 86-15 1-48-29-16-41 14-42z" id="path1342"/><path d="m1813 496-87 3-32-24-28-2-30-15 33-32 82-19 51 13z" id="path1340"/><path d="m1078 602 122-14 18-45 24 18s22 49-3 73c-24 24-82 40-138 28-56-13-23-60-23-60z" id="path4202"/><path d="m1043 575-3-32 81-56 75 42 4 44-42 6-7 14h-25l-25-7-28 1z" id="path4200"/><path d="m412 661 101-64 8-34 27-11 16 16 38-27 31 49-187 138z" id="path1322"/><path d="M474 529c-43-40-79-84-35-101s146-22 158 15c13 36-8 68-40 80-33 12-62 29-83 6z" id="path1320"/><path d="m1605 351-18-51-1-24 44-17 21-3 56 44 1 44z" id="path1332"/><path d="m1434 230-80 6-29-26v-45l32-18 33-1 40 43z" id="path1330"/><path d="m529 102-2-43 8-26 36-21 29 18 17 25v53l-46 6z" id="path1328"/><path d="m1201 1722-4-49-1-30 23-28 57 34 38 19-6 62-45 36z" id="path1390"/><path d="m1095 1622-108-84-4-41 30-27 22-3 102 62 11 27v31z" id="path1388"/><path d="m691 1706-4-21 22-10-3-33 31-7 66 26 17 22-1 35-52 46-43-41-10 9z" id="path1386"/><path d="m690 1432-1-26 25-23 11-5 31 17 11 13-2 27-19 13-36 1z" id="path1382"/><path d="m710 1372-42 17-41-83-4-28 24-11 26 9 30 44z" id="path1380"/><path d="m694 1290-50-32 20-99 12-15 98 52 13 82-5 21z" id="path1384"/><path d="m451 1290-4-21 57-55 43 23 1 30-25 28-19-11-19 26z" id="path1374"/><path d="m408 1209 13-6 2-12 31 3 23 20-1 30-31 27-36-21z" id="path1372"/><path d="m628 1188-65-41-4-24 20-28 31 15 45 29 7 27z" id="path1378"/><path d="m510 1216-5-39 21-14 2-22 18-4 66 45 6 32-45 36z" id="path1376"/><path d="m425 1173-4-32 20-27 17-11 30 32-5 34-28 28z" id="path1370"/><path d="m315 1122-2-41 14-18 18-1 28 24 1 30-7 25-31 9z" id="path1368"/><path d="m327 1016-21 17-13-12-10-31 10-26 26-5 13 40z" id="path1364"/><path d="m273 1049-27-4-11-10 18-27 21-12 20 22 4 21z" id="path1366"/><path d="m116 1085-29-26 4-20 168-62 12 8-3 10z" id="path1352"/><path d="m269 967-195 76-29-24 3-17 95-23 8-16 17-10 12 5 68-11 19 4z" id="path1348"/><path d="m240 921 31-12 15 10v27l-17 7-28-17z" id="path1360"/><path d="m288 936 13-17 17-9 10-14h13l6 11 15 29v6l-62 17-12-20z" id="path1362"/><path d="m290 872 48-43 46 25-9 34-67 2z" id="path1358"/><path d="m258 913-17-21-3-26 6-24 21-2 23 28-1 25z" id="path1356"/><path d="m203 938-31-21-2-50 30-8 18 8 22 26-2 22z" id="path1354"/></g></svg>
  <div id="card"></div>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文