Is there any way to break every word of a span text into children?

Asked

Viewed 71 times

2

Imagine that I identify within a text a span element that starts and ends with the class "color-green":

<span data-id="1" class="cor-verde">O texto está assim <strong>parte em negrito</strong></span>

Using Javascript, you would have to turn this text into an output by dividing it through the spaces of words:

 <span data-id="1"><span class="cor-verde">O</span> <span class="cor-verde">texto</span> <span class="cor-verde">está</span> <span class="cor-verde">assim</span> <span class="cor-verde"><strong>parte em negrito</strong></span></span>

The proposal is so that when exporting a PDF, this element is recognized in the layout, that today only in HTML this formatting works.

I tried something like this, but for some reason it’s breaking the text:

window.onload = function(){ 
 var formatContentToPrint = function (content) {
     var marks = content.querySelectorAll('span');
    //  var iel = document.getElementsByTagName("i");

     if (marks.length) {
         for(var i in marks) {
         if(marks[i].childNodes.length) {
                        for(var n in marks[i].childNodes) {
                            var nodeRm = marks[i].childNodes[n];
                           if (nodeRm.nodeName == 'I') {
                               marks[i].removeChild(nodeRm);
                             break;
                          }
                       }
                     }
             if (marks[i].attributes && marks[i].attributes.length) {
                 for(var j in marks[i].attributes) {


                     if(marks[i].attributes[j].name == 'data-id') {
                         var mark = document.querySelector('[data-id="'+marks[i].attributes[j].value+'"]');
                         var listAttributes = [];
                         for (var m in mark.attributes) {
                             if(typeof mark.attributes[m] == "object") {
                                listAttributes.push(mark.attributes[m].name+'="'+mark.attributes[m].value+'"');
                             }
                         }    

                         mark.removeAttribute('class');
                         var words = mark.innerHTML.split(' ');
                         var spans = [];
                         if (words.length) {
                             for (var k in words) {
                                 spans[k] = '<span '+listAttributes.join(' ')+'>'+words[k]+'</span>';
                             }
                         }
                         mark.innerHTML = spans.join(' ');

                     }
                 }
             }
         }
     }
     return content;
 }

var content = document.getElementById('content');
   content = formatContentToPrint(content);

doc.innerHTML = content.innerHTML;
}

In the example of Fiddle works normal, i simulated a situation that he breaks the code - click here

When I use this method in a text of my system, it is breaking, see in the images:

inserir a descrição da imagem aqui

inserir a descrição da imagem aqui

1 answer

2


One way to do this is by breaking the text of spans by space then using regular expression (in case there are tags <>) and make substitutions by adding each word inside a span:

document.querySelectorAll("span").forEach(function(e){
   var classe = e.className; // pega a class do span principal
   var novo_html = '';
   Array.from(e.childNodes).filter(function(e){
      return e.textContent.replace(/\s{2,}/, '');
   }).forEach(function(e){
      if(e.nodeType == 3){
         e.textContent.trim().split(' ').filter(function(e){
            return e;
         }).forEach(function(e){
            novo_html += '<span class="'+ classe +'">'+ e + '</span> ';
         });
      }else{
         novo_html += '<span class="'+ classe +'">'+ e.outerHTML + '</span> ';
      }
   });
   e.removeAttribute("class"); // remove a classe da span principal
   e.innerHTML = novo_html.trim(); // substitui o HTML
});
.cor-verde{
   color: green;
}

.cor-vermelho{
   color: red;
}
<span data-id="1" class="cor-verde">O texto está assim <strong>parte em negrito</strong></span>
<br>
<span data-id="2" class="cor-vermelho">"texto" qualquer <strong>parte em negrito</strong> <em>parte em itálico</em></span>

If you run the above code and look at the inspector of elements of the browser, you will see that each word is inside a span.

  • 1

    Cool, it looks like it worked: https://jsfiddle.net/ivanferrer/j3km5yd4/6/

  • Error now using real case: https://jsfiddle.net/ivanferrer/c7jpd052/

  • I’m out now but then I’ll look

  • Thanks, quiet...

  • Show me the full text that is giving error.

  • The link is complete: https://jsfiddle.net/ivanferrer/takvxsen/

  • The link I posted from the actual case above is also a full text...

  • Here is the same example, but using the old method, you still have a problem: https://jsfiddle.net/ivanferrer/takvxsen/3/

  • Take a look now.

  • Thanks @Sam, I think now it’s gone for good... without breaking anything.

Show 5 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.