locket23
locket23

Reputation: 81

Add class to tag name

I want to access the direct children of element a with the tag h1( the first two h1) . I' ve done it like this :

var h =a. getElementsByTagName('h1');

And after that I have to add a class to those h1 which don't have a class attribute . How can I do this ? I thought of something like :

 if (h.classList.contains(NULL) == true)
     h.classList.add('class'); 

This is the html body :

  <body>
          <a> 
           <h1></h1>
           <h1></h1>
           <div>
                <h1></h1>
           </div>
        </a>

</body>

Upvotes: 0

Views: 2463

Answers (3)

zer00ne
zer00ne

Reputation: 43920

Using this selector, you will select the first and second child of any anchor but will ignore the 3rd, 4th, etc. h1 child.

a > h1:nth-child(-n+2)

Snippet 1 demonstrates the use of this selector with querySelectorAll(). If you need the logic of:

If first or second h1 does have a class then don't assign a class.

See Snippet 2 below.

SNIPPET 1

/* Collect all first and second h1 that are direct descendants 
(i.e. children) of any anchor and put them in a NodeList.*/
var x2H1 = document.querySelectorAll('a > h1:nth-child(-n+2)');

// Total number of h1 in NodeList x2H1
var xQty = x2H1.length;

// Declare increment variable for 'for' loop
var i;

// 'for' loop will add the class .firstTwo to each item in NodeList
for (i = 0; i < xQty; i++) {
  x2H1[i].classList.add('firstTwo');
}
.firstTwo {
  color: red;
  font-size: 50px;
}
<html>

<head>
</head>

<body>
  <header>
    <a>
      <h1>H1</h1>
      <h1>H1</h1>
      <div>
        <h1>Nested H1</h1>
      </div>
    </a>
  </header>
  <a>
    <div>
      <h1>Nested H1</h1>
    </div>
    <h1>H1</h1>
  </a>
  <section>
    <a>
      <h1>H1</h1>
      <h2>H2</h2>
    </a>
    <h1>H1 descendant of section</h1>
  </section>
  <a>
    <h1>H1</h1>
    <h1>H1</h1>
    <h1>H1 third child of anchor</h1>
  </a>

Note: For simplicity, classList.add() was used instead of seeing if the h1 had a class. If for some reason you need to add a class to a h1 but not add a class to a h1 that does have a class, (as the logic is in OP's code) then use Snippet 2:

SNIPPET 2

/* Collect all first and second h1 that are direct descendants 
(i.e. children) of any anchor and put them in a NodeList.*/
var x2H1 = document.querySelectorAll('a > h1:nth-child(-n+2)');

// Total number of h1 in NodeList x2H1
var xQty = x2H1.length;

// Declare increment variable for 'for' loop
var i;

/* 
'for' loop will:
  1. Determine if h1 has a class already
  2. If it does, then it is logged in 
  the console as being so.
  3. if not, then it will add the class
  .firstTwo to it.
*/
for (i = 0; i < xQty; i++) {
  x2H1[i].getAttribute('class') ? console.log('Already has a class') :
    x2H1[i].classList.add('firstTwo');
}
.firstTwo {
  color: red;
  font-size: 50px;
}
<html>

<head>
</head>

<body>
  <header>
    <a>
      <h1 class='skip'>H1</h1>
      <h1>H1</h1>
      <h1>H1</h1>
      <div>
        <h1>Nested H1</h1>
      </div>
    </a>
  </header>
  <a>
    <div>
      <h1>Nested H1</h1>
    </div>
    <h1>H1</h1>
  </a>
  <section>
    <a>
      <h1>H1</h1>
      <h2>H2</h2>
    </a>
    <h1>H1 descendant of section</h1>
  </section>
  <a>
    <h1>H1</h1>
    <h1>H1</h1>
    <h1>H1 third child of anchor</h1>
  </a>

Using .getAttribute('class') will actually detect the attribute class whether it is assigned a value or not. So if for example:

 <h1 class=''>H1 with class but no value</h1>

That would be determined as true as it would if as an example:

 <h1 class='klass'>H1</h1>

If you want to ensure that every class has a value then as Alexy S. has suggested is the way to detect whether a h1 has a class with a value. For example:

    if (x2H1[i].classList.length === 0) {
        x2H1[i].classList.add("firstTwo");
    }

Upvotes: 1

Alexey Soshin
Alexey Soshin

Reputation: 17721

You can do it like that:

    var h = document.getElementsByTagName('h1');

    // No fancy forEach
    for (var i = 0; i < h.length; i++) {
        if (h[i].classList.length === 0) {
            h[i].classList.add("class");
        }
    }
.class {
  color:red;
  }

.some_class {
  color: blue;
  }
<body>
<a>
    <h1>Heading 1</h1>
    <h1 class = "some_class">Heading 2</h1>
    <div>
        <h1>Heading 3</h1>
    </div>
</a>
</body>

Upvotes: 3

Joseph
Joseph

Reputation: 119847

getElementsByTagName returns an array-like structure containing all elements that match the name, in this case all <h1>. You need to loop through it to access each <h1>.

Upvotes: 1

Related Questions