marco
marco

Reputation: 312

toggle many hidden objects at once

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>

Upvotes: 0

Views: 55

Answers (1)

Mark Schultheiss
Mark Schultheiss

Reputation: 34217

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>

Upvotes: 1

Related Questions