Home > Blockchain >  Split sentence into letters and add dynamic class (position of that letter) to it
Split sentence into letters and add dynamic class (position of that letter) to it

Time:11-28

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)

Show code snippet

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  ;     
}
  • Related