-4

I have three headings with the same ID. All headings are yellow but I would like to change color. I have used the following code but only the first Hello1 is changed to red. My idea was that all heading with id="MP" should be now red. What did I do wrong?

I have also tried with TagName but the result is worse - all headings are still yellow :(

<!DOCTYPE html>
<html>
    <body> 
        <h1 id="MP" style="color: #ffff00; font-size: 20px;">Hello1</h1>
        <h1 id="MP" style="color: #ffff00; font-size: 15px;">Hello2</h1>         
        <h1 id="MP" style="color: #ffff00; font-size: 10px;">Hello3</h1>  
             <script type="text/javascript"> 
                document.getElementById("MP").style.color="red";
                //document.getElementsByTagName("h1").style.color="blue";
             </script>
    </body> 
</html>

Help is appreciated! Thanks!

Lidia
  • 23
  • 2
  • 4
  • *I have three headings with the same ID.* <-- You're not allowed to do that. It's invalid HTML. – Scott Marcus Feb 05 '21 at 15:01
  • Ok, now I have three headings with the same class name (class names should not be unique) and try to use document.getElementsByClassName("MP").style.color="red"; But nothing is happening, all headings are still yellow. Any suggestions? – Lidia Feb 05 '21 at 15:17
  • You're trying to set the color of the collection of elements, which can't be done. See my answer below. – Scott Marcus Feb 05 '21 at 15:23

2 Answers2

1

As I mentioned in my comment, it is invalid to have multiple elements with the same id. The purpose of an id is to uniquely identify an element, so having more than one with the same id defeats that purpose.

Next, .getElementById() (notice it's not called .getElementsById()) only returns a reference to the first matching element it finds, so after finding the first one, it stops and that's why only the first h1 is changing its color.

If you want to group together elements that are somehow related, you can give them all the same class. Then, you can locate all the class members with .querySelectorAll(). This will return a collection, which you can then loop over and work with each element within the collection as you wish.

Also, avoid inline styles whenever you can. As you saw with your original code, you had to repeat the same styling instructions 3 times because you wanted the same style in 3 places. Instead, create a pre-defined CSS class that each of the elements can just use.

Here all that is put together.

<!DOCTYPE html>
<html>
<head>
  <title>Styling with JavaScript</title>
  
  <style>
    /* Use pre-defined CSS classes whenever possible
       instead of inline styles in your HTML    */
    .heading { color: #ffff00; font-size: 20px; }
    
    .newColor { color:#00f; }
  
  </style>
</head>
<body>
  <!-- See how clean the HTML is now? -->
  <h1 class="heading">Hello1</h1>
  <h1 class="heading">Hello2</h1>         
  <h1 class="heading">Hello3</h1> 

  <script> 
    // Get all the elements that match the CSS selector
    // passed into .querySelectorAll() into a collection
    // and loop over the collection
    document.querySelectorAll(".heading").forEach(function(element){
      // Override the original color by adding an additional class
      element.classList.add("newColor");
    });
  </script>
  
</body>
</html>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • Turns out, we have a dupe for this problem too... https://stackoverflow.com/questions/10693845/what-do-queryselectorall-getelementsbyclassname-and-other-getelementsby-method – Heretic Monkey Feb 05 '21 at 15:39
  • @HereticMonkey That's not a dupe of this question and actually is centered around the use of live node lists, which should almost always be avoided, especially in loops. – Scott Marcus Feb 05 '21 at 15:41
0

I have three headings with the same ID.

This is the problem! IDs are meant to be unique! Use a class attribute for this!

More info on MDN

Here is says: If the id value is not the empty string, it must be unique in a document.

Dom
  • 734
  • 3
  • 8
  • 1
    If you do not have access to change the structure of your document, you can use `document.querySelectorAll("#MP");` to get access to all elements with this `id`. – D M Feb 05 '21 at 15:00
  • document.querySelectorAll("#MP").style.color="red"; did not work for me – Lidia Feb 05 '21 at 15:08
  • This explains a little of the problem, but not the solution. Since the problem is really explained in the link, this should be a comment, not an answer. – Scott Marcus Feb 05 '21 at 15:22
  • @ScottMarcus — "Use a class attribute" — It provides the solution. – Quentin Feb 05 '21 at 15:29
  • @Quentin Is that really a solution or something that the OP now has to Google? – Scott Marcus Feb 05 '21 at 15:33
  • @ScottMarcus — Answers shouldn't need to provide introductory guides to basic concepts. – Quentin Feb 05 '21 at 15:35
  • @Quentin I think that depends on how someone gauges "basic". It's pretty clear the OP doesn't know about classes, so just saying "use classes" isn't super helpful. – Scott Marcus Feb 05 '21 at 15:37