:nth-child(2)
seems to select something inside of child 1.
child 1 and child 3 work correctly.
It doesn't seem to involve the type of tag, as several similar but different questions do. I don't see the problem.
/
var one = document.querySelector('div.rules :nth-child(1)');
var two = document.querySelector('div.rules :nth-child(2)');
var three = document.querySelector('div.rules :nth-child(3)');
one.classList.add('arule');
two.classList.add('brule');
three.classList.add('crule');
.arule {
background-color: yellow;
}
.brule {
background-color: red;
}
.crule {
background-color: blue;
}
<div class="rules">
<div>
<label for="rule1">Rule1</label>
<input id="rule1">
</div>
<div>
<label for="rule2">Rule2</label>
<input id="rule2">
</div>
<div>
<label for="rule3">Rule3</label>
<input id="rule3">
</div>
</div>
:nth-child(2)
seems to select something inside of child 1.
child 1 and child 3 work correctly.
It doesn't seem to involve the type of tag, as several similar but different questions do. I don't see the problem.
https://jsfiddle/rhedin/em56jk9v/
var one = document.querySelector('div.rules :nth-child(1)');
var two = document.querySelector('div.rules :nth-child(2)');
var three = document.querySelector('div.rules :nth-child(3)');
one.classList.add('arule');
two.classList.add('brule');
three.classList.add('crule');
.arule {
background-color: yellow;
}
.brule {
background-color: red;
}
.crule {
background-color: blue;
}
<div class="rules">
<div>
<label for="rule1">Rule1</label>
<input id="rule1">
</div>
<div>
<label for="rule2">Rule2</label>
<input id="rule2">
</div>
<div>
<label for="rule3">Rule3</label>
<input id="rule3">
</div>
</div>
Share
Improve this question
edited Jan 15, 2019 at 23:14
Temani Afif
275k28 gold badges366 silver badges486 bronze badges
asked Jan 15, 2019 at 21:46
user2171796user2171796
4374 silver badges17 bronze badges
1
- Please don't edit your question to include your answer or how you understand this based on the answers you got. Either ask for clarification in case you didn't get everything (using ments) or answer you own question if you want to provide your version of answer – Temani Afif Commented Jan 15, 2019 at 23:16
6 Answers
Reset to default 4try like this:
var one = document.querySelector('div.rules div:nth-child(1)');
var two = document.querySelector('div.rules div:nth-child(2)');
var three = document.querySelector('div.rules div:nth-child(3)');
one.classList.add('arule');
two.classList.add('brule');
three.classList.add('crule');
.arule {
background-color: yellow;
}
.brule {
background-color: red;
}
.crule {
background-color: blue;
}
<div class="rules">
<div>
<label for="rule1">Rule1</label>
<input id="rule1">
</div>
<div>
<label for="rule2">Rule2</label>
<input id="rule2">
</div>
<div>
<label for="rule3">Rule3</label>
<input id="rule3">
</div>
</div>
I made div.rules div:nth-child(2)
Here is an explanation of what went wrong. It was the result of your selector. The oddity in the way it played out was due to your html structure, and using querySelector.
div.rules :nth-child()
This will first target the <div class="rules">
element. Then, it will look for all elements which are the nth-child inside of that div because of the space between the two selectors. Following that, using
querySelector
will select the first element of the matched set.
This is why you ended up getting the first <div>
with :nth-child(1)
, because it in fact matched every single nth-child(1), but taking the first result was coincidentally the element you expected.
However, :nth-child(2)
matching every second child element was far too wide of a net, and ended up getting the second child in the first div, and since that was the first result, that was where the red background showed up.
The final curiosity of :nth-child(3)
seeming to actually hit the proper element was only because there is only one third child element in all of that html, and it was the one which you expected, although as explained for reasons other than assumed.
document.querySelector
will return one element and as you can see your input is red because the rule div.rules :nth-child(2)
apply to it as it's the second child inside his parent element, so you will select it (since it es first in the DOM tree) and not the div.
You should use >
selector if you want to target only the divs or use div:nth-child()
or consider document.querySelectorAll
to get all the elements that match the selector:
var one = document.querySelector('div.rules > :nth-child(1)');
var two = document.querySelector('div.rules > :nth-child(2)');
var three = document.querySelector('div.rules > :nth-child(3)');
one.classList.add('arule');
two.classList.add('brule');
three.classList.add('crule');
/*this will add border to all inputs and second div*/
var all = document.querySelectorAll('div.rules :nth-child(2)');
for(var i=0;i<all.length;i++) {
all[i].style.border="3px solid green";
}
.arule {
background-color: yellow;
}
.brule {
background-color: red;
}
.crule {
background-color: blue;
}
<div class="rules">
<div>
<label for="rule1">Rule1</label>
<input id="rule1">
</div>
<div>
<label for="rule2">Rule2</label>
<input id="rule2">
</div>
<div>
<label for="rule3">Rule3</label>
<input id="rule3">
</div>
</div>
You want to be targeting only the direct children of div.rules
. Since you're using querySelector
, it only returns the first result, for :nth-child(2)
, that's the input in the first div (you'll notice that it has a red background in your example)
var one = document.querySelector('div.rules > :nth-child(1)');
var two = document.querySelector('div.rules > :nth-child(2)');
var three = document.querySelector('div.rules > :nth-child(3)');
one.classList.add('arule');
two.classList.add('brule');
three.classList.add('crule');
.arule {
background-color: yellow;
}
.brule {
background-color: red;
}
.crule {
background-color: blue;
}
<div class="rules">
<div>
<label for="rule1">Rule1</label>
<input id="rule1">
</div>
<div>
<label for="rule2">Rule2</label>
<input id="rule2">
</div>
<div>
<label for="rule3">Rule3</label>
<input id="rule3">
</div>
</div>
A simple solution would be to add a plain div in your selector (jsfiddle)
var one = document.querySelector('div.rules div:nth-child(1)');
var two = document.querySelector('div.rules div:nth-child(2)');
var three = document.querySelector('div.rules div:nth-child(3)');
one.classList.add('arule');
two.classList.add('brule');
three.classList.add('crule');
There is a awesome website about this kind of selector. You should definitly give it a shot: CSS Diner.
At least specify that you mean direct children, as there may be multiple nested ones, and program can't find out what you mean:
var one = document.querySelector('div.rules > :nth-child(1)');
var two = document.querySelector('div.rules > :nth-child(2)');
var three = document.querySelector('div.rules > :nth-child(3)');
one.classList.add('arule');
two.classList.add('brule');
three.classList.add('crule');