I am making a function for my site where I set a data attribute which contains the nth-child number of that element.
My HTML markup:
<
You can split the text at the spaces at get the last word from each split-array:
var hards = document.getElementsByClassName('hardware');
for (var i=0; i < hards.length; i++) {
var hardText = hards[i].innerText || hard[i].textContent;
var hardList = hardText.split(' ');
var hardLast = hardList[hardList.length - 1];
alert(hardLast);
}
I am using || here because Firefox does not support innerText
, while IE does not support textContent
.
If the elements only contain text then innerHTML
can be used instead of innerText/textContent
.
Check out this previous answer HERE.
It uses
var i = 0;
while( (child = child.previousSibling) != null )
i++;
//at the end i will contain the index.
Simply incrementing the index linearly will only work if all the elements matching that class name are the only element children of the same parent, with no other elements that could interfere with :nth-child()
, as shown exactly in the given markup. See this answer for an explanation on how other elements might interfere. Also review the Selectors spec on :nth-child()
.
One way to achieve this that is more foolproof is to loop through the child nodes of each element's parent node, incrementing a counter for each child node that is an element node (since :nth-child()
only counts element nodes):
var selector = document.getElementsByClassName('hardware');
for (var i = 0; i < selector.length; i++) {
var element = selector[i];
var child = element.parentNode.firstChild;
var index = 0;
while (true) {
if (child.nodeType === Node.ELEMENT_NODE) {
index++;
}
if (child === element || !child.nextSibling) {
break;
}
child = child.nextSibling;
}
element.dataset.number = index;
}
JSFiddle demo
Note that this will apply the correct index regardless of where the given element is in the DOM:
If a particular section.hardware
element is the first and only child of a different section
, it will be assigned the correct index of 1.
If a .hardware
element is the second child of its parent, even if it is the only one with that class (i.e. it follows some other element without the class), it will be assigned the correct index of 2.
I'm going to answer the questions with the following assumptions:
hardware
classed elements are all siblings<body>
<section class="hardware">some text, nth-child is zero</section>
<section class="software"></section>
<section class="hardware">some text, nth-child is two</section>
</body>
(I'm making these assumptions, because this is the problem I'm facing, thought it could be useful)
So the main difference is that instead of querying the elements that belong to a given class, I'm going to get the (direct) children of the body
, and filter them.
Array.from(document.body.children)
.map((element, index) => ({element, index}))
.filter(({element}) => element.classList.contains('hardware'))
The resulting array will look like this:
[
{element: section.hardware, index: 0}
{element: section.hardware, index: 2}
]
When you say "number", do you mean 1, 2, etc or "one", "two", etc?
If 1, 2, etc, then the number is simply i+1...
If "one", "two", etc, then you need to get the text inside the element, then probably use a Regexp to parse it and get the value you want.