简体   繁体   中英

Change color of all elements in class on click JavaScript

I have an image (SVG) of a human body. I would like to use JavaScript so that when I click a particular area (say, the lower leg) then all of the elements with the class "lower-leg" (even if not clicked) have their color changed -- this makes it much easier for the user.

Here is the JavaScript I currently have:

function changeclassstyle() {
  var c = document.getElementsByClassName("lower-leg");
  for (var i=0; i<c.length; i++) {
    c[i].style.fill = "red";
  }
}

The problem with this code is that it is only generalized for "lower-leg". I may have over a dozen classes I would like this to work for and don't think it is efficient to write 12 functions with the only change being the class name. Is there a way to grab what class was selected and then input that in the function?

--

Additionally, I would love to figure out how, once that section of the body is selected, I can store the class name. I would, in the end, want to store the selection, along with other inputted information in a database. But, this may be for a future question unless someone can help!

Here's how I would do it (tested on a couple of div 's).

What we're doing is passing the event object to the event handler (your changeclassstyle() function). It then uses the class of the clicked-on item (the event target's class) and changes everything else on that page with that same class name to use your new desired CSS style.

 function changeclassstyle(e) {

           // Get all items that have the same class as the item that was clicked
            var limbs = document.getElementsByClassName(e.target.className); // for div's and the like

           // var limbs = document.getElementsByClassName(e.target.className.baseVal); // turns out this is needed for SVG items 


           // "limbs" is an HTMLCollection, not an array, so functions like .foreach won't work; C-style for-loops or modern for/let/of loops are better

            for (let item of limbs) {
                item.style.backgroundColor = 'red'; 
              // item.style.fill = 'red';  // This is probably what you need for your SVG items
            }

         // You could still use your C-style for loop if needed/wanted
            /*
               for (var i=0; i<limbs.length; i++) {
                limbs[i].style.fill = "red";
               }
            */
        }

The onchange call looks like this (using my div as the example):

        <div class="upper-arm" onclick="changeclassstyle(event)">
        </div>

        <div class="lower-leg" onclick="changeclassstyle(event)">
        </div>

The whole example with simple div's.

<html>
    <head><title>stuff</title></head>
    <body>
        <script type="text/javascript">
        function changeclassstyle(e) {
            // For debugging. You may want to expand 'e' here in your browser's debug tools if you're not seeing the values you need/want
            console.log(e)
            var limbs = document.getElementsByClassName(e.target.className.baseVal);
            for (let item of limbs) {
                item.style.backgroundColor = 'red';  
            }
        }
        </script>

        <style type="text/css">
        div {
            height: 100px;
            width: 100px;
            background-color: 'white';
            border: 1px solid black;
        }
        </style>

        <div class="upper-arm" onclick="changeclassstyle(event)">
        </div>
        <div class="upper-arm" onclick="changeclassstyle(event)">
        </div>
        <div class="upper-arm" onclick="changeclassstyle(event)">
        </div>

        <div class="lower-leg" onclick="changeclassstyle(event)">
        </div>
        <div class="lower-leg" onclick="changeclassstyle(event)">
        </div>
        <div class="lower-leg" onclick="changeclassstyle(event)">
        </div>
    </body>
</html>

You can use parameters in function where you pass class and color like below

function changeStyle(cls,clr) {
  let elems = document.getElementsByClassName(cls);
  if(!elems) return;
  for (let elem of elems) {
      elem.style.color = clr;
  }
}

As per the iteration of many classes like i said you can store classes in array and iterate each of them.

  let classes = ['one','two','three','four'];

  classes.forEach(function (cls) {
    changeStyle(cls,"red");
  });

You can play with fiddle here if you want to test/experiment: https://jsfiddle.net/thrL5uqw/8/

Note: Change style property as you wish, For now i have used color for demo

I'm a bit late to the party, but here's my take on the problem.

Like the others told you, you'll need to use an additional parameter to your function to specify the class you want to modify your elements (or try to figure out the class from the clicked element), therefore you should have something like that:

/**
 * This function will handle the click event on one of the part of the SVG.
 * @param {string} lClass This the class of the element to modify
 */
function handleClick(lClass) {
  for (let e of document.getElementsByClassName(lClass)) {
    // Here you can do all the changes you need on the SVG element.
    e.style.fill = "red";
  }
}

And when it comes to the event binding, you could do like the other suggested and add the onclick event binding propery on the HTML Element, or you could bind it in you JS with the addEventListener function (that way you don't have to repeat the onclick property on each of your SVG elements).

// For each element of all the listed class, bind the "click" event to the handleClick function
const listenClass = [/*List of your classes*/];
for (let l of listenClass) {
  for (let e of document.getElementsByClassName(l)) {
    e.addEventListener('click', handleClick.bind(this, l));
  }
}

Demo: https://plnkr.co/edit/gay2yBaVi5QD868fsTa6?p=preview

I hope it helped.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM