Reputation: 81
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
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.
/* 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:
/* 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
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
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