Quba
Quba

Reputation: 5306

js wrap words into spans without modifying inline html

I have a string variable in JS which holds some texts. It sometimes happens that said text contains HTML tags.

What I need to do is to wrap every word into separate span tag. eg.

This is <p>text</p> => <span>This</span> <span>is</span> <p><span>text</span></p>

Ideally, it should be achieved without the use of JQuery but not necessary.

I've tried a couple of different solutions including Regexes (which work most of the time but not always).

I am using Polymer 2.0 and ShadyDOM.

EDIT

IT also might happen that tags have properties. eg: <span class=”test”>So I have heard.</span> => <span class="test"><span>So</span> <span>I</span> <span>have</span> <span>heard</span></span>

Upvotes: 2

Views: 265

Answers (2)

artgb
artgb

Reputation: 3233

You can create DOM element from string and loop through all child nodes using DOM.childNodes. And then replace the string with the span.

function changeText(s){
    var div = document.createElement('div');
    div.innerHTML = s;
    recurseDomChildren(div, true);
    var str = div.innerHTML.replace(/spfrnt/g, "<span>").replace(/spback/g, "</span>");
    return str;
}
function recurseDomChildren(start, output){
    var nodes;
    if(start.childNodes){
        nodes = start.childNodes;
        loopNodeChildren(nodes, output);
    }
}
function loopNodeChildren(nodes, output){
    var node;
    for(var i=0;i<nodes.length;i++){
        node = nodes[i];
        addSpanToNode(node);
        if(node.childNodes)recurseDomChildren(node, output);
    }
}
function addSpanToNode(node){
    if(node.nodeType != 3) return;
    var tt = node.data;
    var strArr = tt.split(" ");
    var str = "";
    for( var i = 0 ; i < strArr.length; i++) if (strArr[i]){
        str += 'spfrnt' + strArr[i] + 'spback ';
    }
    node.data = str;   
}
console.log("firstCase: ", changeText('<span class="test">So I have heard.</span>'));
console.log("secondCase: ", changeText('This is <p>text</p>'));

Upvotes: 1

J. Pedro
J. Pedro

Reputation: 65

You don't need Regex to accomplish this. Just a few array manipulations.

var str = "Your string of info here";

//Create an array with each word in the string
//Map the array wrapping each word in a <span>
//You can also then join the array by adding .join('') to the end
var res = str.split().map(m => {return `<span>${m}</span>`});

Upvotes: 0

Related Questions