0

I've a page structure like this:

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

These div is positioned absolute with highest z-index thus they are floating over svg image. I want to print console.log(something) when mouse over the circle.

What I've tried:

$('#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 -->

Note that these syntax are working with all other elements on the page except than those lying in or over svg portion(I've tested on a dummy button outside svg on which it was working)

Looking for some help...

Update 2:(More detailed) The below is a short version of code

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

In graph.js there are two sections named as Code-Previous and Code-Later. The mouse hover event is working as expected in the shown situation of graph.js. However if I remove the Code-Later and enable the Code-Previous, hover event doesn't works. Also, I can't remove $("body").html($("body").html()); otherwise svg-line inserted in ".graph" will not render.

Why such behaviour is happening with?

T.M15
  • 366
  • 2
  • 15
  • 1
    use the pointer-events property to stop things getting pointer-events that you don't want. – Robert Longson Mar 29 '21 at 12:44
  • The second version is of course wrong, it makes no sense to try and attach an event handler to the HTMLCollection this method returns. You will have to loop over the elements contained in that collection, and append an event handler for each of them individually. – CBroe Mar 29 '21 at 12:45
  • @CBroe Umm...actually I've copied that second one directly from https://api.jquery.com/hover/ I think it might be a new way in .hover() – T.M15 Mar 29 '21 at 12:51
  • I was not talking about the jQuery version, but the version that uses `getElementsByClassName` – CBroe Mar 29 '21 at 12:53
  • @RobertLongson I've read this https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events and added `pointer-events: none;` to css of svg. Still, circles are not capturing the hover events :( Could you please explain in a bit detail how to do it? – T.M15 Mar 29 '21 at 13:05
  • I assume you want pointer-events: none on the divs, not the svg from your description. If not, please create an actual [mcve] i.e. something that actually runs, ideally using stack snippets. – Robert Longson Mar 29 '21 at 13:11

3 Answers3

0

in the test you have array of nodes, you need for loop to add each of them event

n1koloza
  • 539
  • 5
  • 11
0

Always use plenty of colors and borders on positioned objects; you wouldn't be the first one expecting a mouseover event on a 0 height object

<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>
Danny '365CSI' Engelman
  • 16,526
  • 2
  • 32
  • 49
0

Ok...so after spending around 2 hrs., I found a bug which was actually out of my current knowledge of DOM. I'll be grateful if experienced developers comment their views on this. So the problem was:

Earlier I had a problem of 'Elements Not Rendering on SVG' when injected indirectly to DOM using jQuery. Some great answers on SO suggest that after injection I should do $("body").html($("body").html()) and it will render as usual(kind of refreshing body html).

But the problem in the above case was actually this step which was resolved when I added the code of EventListners after the code of above refreshing. What I think is that(perhaps) refreshing the html of body might be revoking all the EventListners added and that's why I was not able to see mouseHover event (which, ofcourse earlier, were written before this $("body").html($("body").html()) line)

T.M15
  • 366
  • 2
  • 15
  • 1
    As pointed out in your comments by Robert, you are not giving us a minimal reproducible example while asking for help. How can anyone help you when nothing in your code suggests you are dynamically adding content with javascript. Typically if you are going to dynamically add content, you use on. `$('body').on('hover', '.node', function( event ) { event.preventDefault(); });` – Bruce Mar 29 '21 at 17:40