I am trying to wrap each individual word on a webpage in a tag so I can style them individually based on their starting letter.
I have found this method of wrapping each word in a span tag individually, but I can't figure out how to vary the class based on the first letter of the word.
let e = document.getElementById('words');
e.innerHTML = e.innerHTML.replace(/(^|<\/?[^>]+>|\s+)([^\s<]+)/g, '$1<span class="word">$2</span>');
What you're trying to achieve can't be done with regex if you want to reference the individual words.
I've wrote a little snippet that uses document.querySelector() instead
outerText property on the query selector object returns a plain text string which is later converted to an array with split() function
Then it simply loops over the array and appends the style tag and to get the first letter I've used substring() function
const words = document.querySelector("#words").outerText.split(" ");
const wordsDiv = document.querySelector("#words")
wordsDiv.innerHTML = ""
words.map((el) => {
wordsDiv.innerHTML += `<span class="${el.substring(0, 1)}">${el}</span> `
})
<div id="words">red green blue orange</div>
Try this:
let e = document.getElementById('words');
// Create array with words
let words = e.innerHTML.split(' ');
// Object with CSS classes and corresponding letter
const classes = {
a: 'class-one',
b: 'class-two',
// and so on
}
// Return array with the new strings
words = words.map(word => {
const firstLetter = word.substring(0,1);
return `<span class="${classes[firstLetter]}">${word}</span>`;
});
// Join the array and update the DOM
e.innerHTML = words.join(' ');
Here the following is happening:
classes constant must receive, as in the example, the correspondence of each letter with its class;map method, the first letter of the word is being returned and the classes object is accessed with that letter;join to join all the texts separating them with a space.Remembering that if there is more than one space between words, inconsistencies will occur, as the first letter will be a space.
From the string.prototype.replace reference, you can also add a replace function to the method, instead of an string. The replace function has this form.
So, if I didn't misinterpret your problem, you can do something similar to this:
let e = document.getElementById('words');
e.innerHTML = e.innerHTML.replace(/(^|<\/?[^>]+>|\s+)([^\s<]+)/g, function(match, p1, p2) {
const myClasses = {
a: "aword",
b: "bword",
...
}
return `${p1}<span class="${myClasses[p2[0]]}">${p2}</span>'
});