【问题标题】:mousehover on Objects floating over SVG not working [duplicate]鼠标悬停在浮动在 SVG 上的对象上不起作用 [重复]
【发布时间】:2021-03-29 12:42:44
【问题描述】:

我的页面结构是这样的:

<body>
   <svg>...<svg>
   <div><!-- font-awsome circle is here with id='node' --></div>
</body>

这些div 绝对定位,具有最高的 z-index,因此它们漂浮在 svg 图像上。当鼠标悬停在圆圈上时,我想打印 console.log(something)。

我尝试过的:

$('#node').hover(()=>{console.log('mouse in')}, ()=>{console.log('mouse out')})
<!-- not working -->
$('#node').mouseenter(()=>{console.log('mouse in')}).mouseleave(()=>{console.log('mouse out')})
<!-- not working -->
let test = document.getElementById('node');
  test.addEventListener( 
    "mouseenter",
    function (event) {
      console.log("mouse enter node");
    },
    false
  );

<!-- Not working -->

请注意,这些语法适用于页面上的所有其他元素,除了那些位于 svg 部分中或之上的元素(我已经在它工作的 svg 之外的虚拟按钮上进行了测试)

寻求帮助...

更新2:(更详细)以下是代码的简短版本

<!-- graph.html -->
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="./graphStyles.css" />
    <!--FontAwsome-->
    <script
      src="https://kit.fontawesome.com/e51e1b526a.js"
      crossorigin="anonymous"
    ></script>
    <title>graph</title>
  </head>
  <body>
    <svg
      xmlns:svg="http://www.w3.org/2000/svg"
      xmlns="http://www.w3.org/2000/svg"
      class="graph"
    ></svg>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="graph.js" charset="utf-8"></script>
  </body>
</html>

// graph.js

function createNode() {
  $("body").append(
    `<div id=C1 class="fa-stack graph-node fa-1.4rem">
          <i class="fas fa-circle fa-stack-2x"></i>
          <p class="fas fa-stack-1x">C1</p>
        </div>`
  );
  $(".graph").append(`<line id="l1-l2" class="graph-edge" ></line>`);
  $("#l1-l2").attr("x1", 100).attr("y1", 0).attr("x2", 200).attr("y2", 200);

  /* Code-Previous: If kept before label: mylabel
  $(`#C1`).hover(
    () => {
      console.log(`mouse in`);
    },
    () => {
      console.log(`mouse out`);
    }
  );
  */

  $("body").html($("body").html());  // label: mylabel

  // Code-Later: If kept after label: mylabel
  $(`#C1`).hover(
    () => {
      console.log(`mouse in`);
    },
    () => {
      console.log(`mouse out`);
    }
  );
}

$(document).ready(createNode);

/* graphStyles.css */

body {
  background-color: #32c6f8;
  position: relative;
  padding: 0;
  margin: 0;
}

svg {
  background-color: #32c6f8;
  position: absolute;
  left: 0;
  top: 0;
  margin: 0;
  width: 100%;
  height: 100%;
  /* pointer-events: none !important; */
}

.graph-node {
  color: white;
  display: inline-block;
  font-size: 2rem;
  position: absolute;
  z-index: 1000;
}
.graph-node p {
  color: black;
  font-family: monospace;
  font-weight: 900;
  font-size: 1.5rem;
  width: 60%;
  left: 0;
  right: 0;
  margin: auto;
}

.graph-edge {
  position: absolute;
  stroke: white;
  stroke-width: 0.5rem;
  z-index: 100;
}

graph.js 中有两个部分,分别命名为Code-PreviousCode-Later。在graph.js 所示的情况下,鼠标悬停事件按预期工作。但是,如果我删除Code-Later 并启用Code-Previous,悬停事件将不起作用。另外,我无法删除$("body").html($("body").html());,否则插入“.graph”中的 svg-line 将不会呈现。

为什么会发生这种行为?

【问题讨论】:

  • 使用 pointer-events 属性来阻止你不想要的指针事件。
  • 第二个版本当然是错误的,尝试将事件处理程序附加到此方法返回的 HTMLCollection 是没有意义的。您必须遍历该集合中包含的元素,并为每个元素单独附加一个事件处理程序。
  • @CBroe 嗯...实际上我已经直接从api.jquery.com/hover 复制了第二个,我认为这可能是 .hover() 中的一种新方式
  • 我说的不是jQuery版本,而是使用getElementsByClassName的版本
  • @RobertLongson 我已经阅读了这个developer.mozilla.org/en-US/docs/Web/CSS/pointer-events 并将pointer-events: none; 添加到svg 的css 中。尽管如此,圆圈并没有捕捉到悬停事件:(您能否详细解释一下如何做到这一点?

标签: javascript html jquery css svg


【解决方案1】:

在测试中你有节点数组,你需要循环来添加每个事件

【讨论】:

  • 是的...修复了这个问题并仅在一个圆圈上进行了测试...仍然没有阳性结果
【解决方案2】:

始终在定位的对象上使用大量颜色和边框;您不会是第一个期望在 0 高度对象上发生鼠标悬停事件的人

<style>
  #CONTAINER { position: relative; width: 200px; }
  svg        { position: absolute; width: 100%; border: 1px dashed black  }
  .over      { position: absolute; background: gold; border: 1px solid red; }
  .over:hover{ background: green; }
</style>
<div id=CONTAINER>
  <svg>
     <rect id=RECT width="100%" height="100%" fill="pink"></rect>
     <circle cx="50%" cy="50%" r="40%" fill="rebeccapurple"></circle>
  </svg>
  <div class=over style="top:20px;left:50px">hotpink</div>
  <div class=over style="top:50px;left:150px">green</div>
  <div class=over style="top:70px;left:20px;right:70px">blue</div>
</div>
<script>
  document.querySelectorAll(".over").forEach((div) => {
    div.onmouseover = (evt) => {
      RECT.setAttribute("fill", evt.target.innerText);
    }
  });
</script>

【讨论】:

    【解决方案3】:

    好的...所以在花了大约 2 小时后,我发现了一个错误,这实际上超出了我目前对 DOM 的了解。如果有经验的开发人员对此发表意见,我将不胜感激。所以问题是:

    之前我在使用 jQuery 间接注入到 DOM 时遇到了 'Elements Not Rendering on SVG' 的问题。 SO 上的一些很好的答案表明,注入后我应该做$("body").html($("body").html()),它会像往常一样呈现(一种令人耳目一新的正文 html)。

    但上述案例中的问题实际上是这一步,当我添加EventListners的代码时上面刷新的代码之后。我认为是(也许)刷新 body 的 html 可能会撤销所有添加的 EventListners,这就是为什么我看不到 mouseHover 事件(当然,之前写在 $("body").html($("body").html()) 行之前)

    【讨论】:

    • 正如罗伯特在您的 cmets 中指出的那样,您在寻求帮助时并没有给我们一个最小的可重现示例。当您的代码中没有任何内容表明您正在使用 javascript 动态添加内容时,谁能帮助您。通常,如果您要动态添加内容,请使用 on。 $('body').on('hover', '.node', function( event ) { event.preventDefault(); });
    猜你喜欢
    • 2016-12-15
    • 2018-05-20
    • 2015-04-04
    • 2020-07-13
    • 2017-02-07
    • 2013-04-08
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    相关资源
    最近更新 更多