Home > Mobile >  Apply class to specific element based on button hover (with matching pairs)
Apply class to specific element based on button hover (with matching pairs)

Time:09-16

As the title suggest I am trying to apply a class/styling to a specific element (in this case an SVG path) based on its corresponding button.

I have a map of the UK that is split up into regions and corresponding buttons to those regions, and I am trying to style a region based on hovering over a button.

So far I have a list of buttons and regions:

// England Buttons
const grBtn = document.querySelector(".eng-gr");
const seBtn = document.querySelector(".eng-se");
const eeBtn = document.querySelector(".eng-ee");
const emBtn = document.querySelector(".eng-em");
const yhBtn = document.querySelector(".eng-yh");
const neBtn = document.querySelector(".eng-ne");
const nwBtn = document.querySelector(".eng-nw");
const wmBtn = document.querySelector(".eng-wm");
const swBtn = document.querySelector(".eng-sw");

// England Region
const grRgn = document.querySelector(".greater-london");
const seRgn = document.querySelector(".south-east-england");
const eeRgn = document.querySelector(".east-england");
const emRgn = document.querySelector(".east-midlands");
const yhRgn = document.querySelector(".yorkshire-humber");
const neRgn = document.querySelector(".north-east-england");
const nwRgn = document.querySelector(".north-west-england");
const wmRgn = document.querySelector(".west-midlands");
const swRgn = document.querySelector(".south-west-england");

I know I can manually use a function for each button/region like so:

grBtn.addEventListener("mouseover", function () {
    grRgn.classList.add("rgn-hover");
});

grBtn.addEventListener("mouseout", function () {
    grRgn.classList.remove("rgn-hover");
});

But I am trying to figure out how I can do it with one (or a few) functions instead of each button/region (i will eventually be adding the rest of the UK).

Codepen of Project: https://codepen.io/MartynMc/pen/OJZWWer

CodePudding user response:

Just an idea but if you can edit the HTML part and trasform this:

<a href="#" >Greater London</a>

Into this

<a href="#"  data-highlight="greater-london">Greater London</a>

So for each button you specify the SVG class to highlight, you can just use event delegation on the buttons container like this:

let container = document.querySelector(".buttons");
container.addEventListener("mouseover", function (e) {
  let ref = e.target.dataset.highlight;
  if (ref) {
    document.querySelector("."   ref).classList.add("rgn-hover");
  }
});
container.addEventListener("mouseout", function (e) {
  let ref = e.target.dataset.highlight;
  if (ref) {
    document.querySelector("."   ref).classList.remove("rgn-hover");
  }
});

And that's all the JS code you need. The parent receives the event from its children and if the child contains a data-highlight attribute, it finds a node with that class name and adds/removes the css class.

CodePudding user response:

try this:

let arr = [
          { btn: grBtn, rgn: grRgn },
          { btn: seBtn, rgn: seRgn },
          { btn: eeBtn, rgn: eeRgn },
          { btn: emBtn, rgn: emRgn },
          { btn: yhBtn, rgn: yhRgn },
          { btn: neBtn, rgn: neRgn },
          { btn: nwBtn, rgn: nwRgn },
          { btn: wmBtn, rgn: wmRgn },
          { btn: swBtn, rgn: swRgn },
        ];

arr.forEach((item) => {
   item.btn.addEventListener("mouseover", function () {
     item.rgn.classList.add("rgn-hover");
   });

   item.btn.addEventListener("mouseout", function () {
      item.rgn.classList.remove("rgn-hover");
   });
});

  • Related