I 'am trying to split a sentence/word into separate letters and was able to achieve using below code.
var textWrapper = document.getElementById("heading");
textWrapper.innerHTML = textWrapper.textContent.replace(/\S/g, "<span class='letter'>$&</span>");
<h1 class="heading" id="heading">
Hello!
</h1>
Input
<h1> Hello! </h1>
What I get from this
<h1>
<span class="letter">H</span>
<span class="letter">e</span>
<span class="letter">l</span>
<span class="letter">l</span>
<span class="letter">o</span>
<span class="letter">!</span>
</h1>
What I want
<h1>
<span class="letter-1">H</span>
<span class="letter-2">e</span>
<span class="letter-3">l</span>
<span class="letter-4">l</span>
<span class="letter-5">o</span>
<span class="letter-6">!</span>
</h1>
What can I do to achieve this?
textWrapper.innerHTML = textWrapper.textContent.replace(/\S/g, "<span class='letter-{what should I do here?}'>$&</span>");
If it is not possible this way, I am ok with some other way of achieving this.
I have zero knowledge in regex so heres how i would do it
const heading = document.getElementById("heading");
const letters = heading.innerText.split("").map((letter, index) => {
const span = document.createElement("span");
span.innerText = letter;
span.classList.add("letter-" + (index + 1));
return span;
});
heading.innerHTML = "";
letters.forEach((span) => heading.appendChild(span));
You have to use some kind of loop to add the character index also
var textWrapper = document.getElementById( "heading" );
// `<span class='letter-${++index}'>$&</span>`
const text = textWrapper.textContent.trim();
textWrapper.innerHTML = "";
text.split("").forEach((char, i) => {
const span = document.createElement("span");
span.classList.add(`letter-${i + 1}`);
span.textContent = char;
textWrapper.appendChild(span);
})
<h1 class="heading" id="heading">
Hello!
</h1>
If you really want to use regex for this you can pass a callback to replace() and access the match and offset of the match within the entire string.
var textWrapper = document.getElementById('heading');
textWrapper.innerHTML = textWrapper.textContent.replace(
/\S/g,
(match, offset) => `<span class='letter_${offset}'>${match}</span>`
);
console.log(textWrapper.outerHTML);
<h1 class="heading" id="heading">
Hello!
</h1>
If you don't want to rely on the offset but instead want a controlled counter you can increment your own, here using a closure
((c)=>(match) => `<span class='letter_${c++}'>${match}</span>`)(1)
var textWrapper = document.getElementById('heading');
textWrapper.innerHTML = textWrapper.textContent.replace(
/\S/g,
((c) => (match) => `<span class='letter_${c++}'>${match}</span>`)(1)
);
console.log(textWrapper.outerHTML);
<h1 class="heading" id="heading">
Hello!
</h1>