0

I have a blue square and when I hover over it, two other objects should appear.

So far, only one object (the text) appears and the other one (the red square) remains hidden.

How do I make that on hovering the blue square both, the red square and the text appear?

var canvas = document.getElementById("svg_canvas");

var square = document.createElementNS('http://www.w3.org/2000/svg',"rect");
square.setAttribute('x', 100)
square.setAttribute('y',  100)
square.setAttribute('width', 100)
square.setAttribute('height', 100)
square.setAttribute("fill", "blue");
square.setAttribute("class", "HoveringClass");
canvas.appendChild(square);

var hover_text = document.createElementNS('http://www.w3.org/2000/svg', "text");
hover_text.setAttribute('id','termin_text');
hover_text.setAttribute('x', 200)
hover_text.setAttribute('y',  200)
hover_text.setAttribute("class", "hide");
hover_text.textContent = "hello world";
canvas.appendChild(hover_text);

var square2 = document.createElementNS('http://www.w3.org/2000/svg',"rect");
square2.setAttribute('id','termin_rect' + 1);
square2.setAttribute('x', 50)
square2.setAttribute('y',  50 )
square2.setAttribute('width', 50)
square2.setAttribute('height', 50)
square2.setAttribute("fill", "red");
square2.setAttribute("class", "hide");
canvas.appendChild(square2);
<svg id="svg_canvas" viewBox="0 0 1200 600" width="1200px" height="600px" xmlns="http://www.w3.org/2000/svg"></svg>

4
  • 3
    Please edit the question instead of correcting it with comments. Commented Oct 11, 2024 at 13:15
  • 1
    When attempting to run this, it says ReferenceError: i is not defined; what's i? Commented Oct 11, 2024 at 13:16
  • 4
    You might forgot some css/js since your current code does nothing on hover. Please add a minimal reproducible example. Commented Oct 11, 2024 at 13:20
  • 1
    Please edit to add clarity and details - "I have a square and when I hover over it" which square? I see a red and a blue one - perhaps you do not have all the CSS or JavaScript here to reproduce this issue. How are you attaching the event handler for the mouse over/hover here? That is missing from this sample code also. Commented Oct 11, 2024 at 13:32

1 Answer 1

1

I took a slightly different approach by declaring an object for each of the SVG elements. Each object has "attributes" to set.

Key here is I used events to toggle a class, then used that class in CSS to hide the elements with el.classList.toggle('hide');

t.addEventListener('mouseenter', handleEvent);
t.addEventListener('mouseleave', handleEvent);

Note I used a data attribute on the svg to say what to target, then added that to the class for the targets: data-toggletargets=".toggle-target" Note also that I put an "opposite" on the blue box text just by NOT including the hide class to that initially - so it goes from showing to hidden when you mouse over the box and mouse out again.

This differs in that the "visual" display type is whatever the HTML/SVG says not something like display:inline; or some such since we only really care about the hide part.

/* get reference to the canvas */
const canvas = document.getElementById("svg_canvas");
/* setup an object with the attributes for each element we want to set */
const elements = [{
  name: "square1",
  type: "rect",
  textContent: "mouse over",
  attributes: {
    id: "square1",
    "data-target": "toggle-target",
    x: 100,
    y: 100,
    width: 100,
    height: 100,
    fill: "blue",
    class: "hovering-sq"
  }
}, {
  name: "happytext",
  type: "text",
  textContent: "mouse over",
  attributes: {
    x: 110,
    y: 150,
    fill: "cyan",
    class: "toggle-target"
  }
}, {
  name: "square2",
  type: "rect",
  attributes: {
    id: "square2",
    x: 50,
    y: 50,
    width: 50,
    height: 50,
    fill: "red",
    class: "target-sq hide toggle-target"
  }
}, {
  name: "textthing",
  type: "text",
  textContent: "howdy doodee",
  attributes: {
    id: "textthing",
    x: 200,
    y: 200,
    fill: "green",
    class: "hide me toggle-target"
  }
}];
/* now using the object above create an element with the attributes */
elements.forEach((prop) => {
  let el = document.createElementNS('http://www.w3.org/2000/svg', prop.type);
  const attributes = prop.attributes;
  if (prop.hasOwnProperty('textContent')) {
    el.textContent = prop.textContent;
  }
  for (const attr in attributes) {
    el.setAttribute(attr, attributes[attr]);
  }
  canvas.appendChild(el);
});
/* get the element we want to use for the mouse enter/leave */
const t = canvas.querySelector('.hovering-sq');
/* handle the event for enter/leave */
function handleEvent(event) {
  const container = event.target.closest('svg');
  const targets = container.dataset.toggletargets;
  const hiders = container.querySelectorAll(targets);
  hiders.forEach((el) => {
    el.classList.toggle('hide');
  });
}
/* set up the event handlers */
t.addEventListener('mouseenter', handleEvent);
t.addEventListener('mouseleave', handleEvent);
.hide {
  display: none;
}
<svg id="svg_canvas" viewBox="0 0 1200 600" width="1200px" height="600px" xmlns="http://www.w3.org/2000/svg" data-toggletargets=".toggle-target"></svg>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.