I am new to js and I am trying to loop through elements by class name and make a change to the element's textcontent using javascript. The following is what I have so far, but this does not work.
<script type="text/javascript">
function dformat(i) {
var hasDate = document.getElementsByClassName("dformat")[i].textContent.trim().includes("/");
if(hasDate === false) {
window.setTimeout(dformat, 100); /* this checks the flag every 100 milliseconds*/
} else {
dateString = document.getElementsByClassName("dformat")[i].textContent.trim();
const options = { year: 'numeric', month: 'short', day: 'numeric' };
let dateArr = dateString.split("/");
var sMonth = dateArr[0];
var sDay = dateArr[1];
var sYear = dateArr[2];
let newDateString = sYear + "/" + sMonth + "/" + sDay
let newDate = new Date(newDateString);
document.getElementsByClassName("dformat")[i].textContent=newDate.toLocaleDateString('en-us', options);
}
}
var ditems = document.getElementsByClassName("dformat");
for (var i = 0; i < ditems.length; i++) {
dformat(i);
}
</script>
The following is an example of one of the elements
<span class="dformat">26/06/1992</span>
The expected output would be to have changed text on each of the elements with class dformat
Update: I tried the same function with getelementbyid on a single element (i.e without a for loop) and got the expected result. I have trouble doing the same on a set of elements by classname instead of a single element by id.
There's nothing wrong with your for loop, the problem is with your
Date
objection construction.Date
s cannot be created with the YYYY/MM/DD format. (See warning section here) What you instead need to do is pass the year, month, and day as parameters to the constructor.Some other notes...
You don't need to use
document.getElementsByClassName
to find the elements each time. You can simply pass the element directly to the function.Here's a code snippet showing this in action.
Secondly, if you use
setTimeout
, you will need to pass the element to the function. As you have it, the function will be called with no arguments, so it would break if it ever found something without a/
. You can see how I did it above to fix that.I'm a little suspicious of using
setTimeout
in this way. This only allows the spans to be formatted once, if you really want continuous monitoring then you you will need to constantlysetTimeout
outside the function definition in the main script. Or if you just need to wait for the document to be ready, you should place your scripts after your HTML content and that will not be a problem. (See here). I won't speculate further since that isn't the purpose of this question, but I wanted to let you know that something seems wrong there.