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>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
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.
CodePudding user response:
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));
CodePudding user response:
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>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
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>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
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>
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You can test this code :
var content = document.getElementById('heading').innerHTML;
content = content.toString();
content = content.split();
document.getElementById('heading').innerHTML = '';
var cpt = 1;
for (let i = 0; i < content.length; i ) {
const element = content[i];
document.getElementById('heading').appendChild("<span class='letter-" cpt "'>" element "</span>");
cpt ;
}