2

I need to create a way to encapsulate all non-html words in a html page with html. An example:

<p id="paragraph"><a href="http://www.google.com">Google it!</a>But I <b>must</b> explain to you</p> 

should be changed to

<p id="paragraph"><a href="http://www.google.com"><span id="word1">Google</span> <span id="word2">it!</span></a><span id="word3">But</span> <span id="word4">I</span> <b><span id="word5">must</span></b> <span id="word6">explain</span> <span id="word7">to</span> <span id="word8">you</span></p> 

I have tried to extract all words:

group_text = $("#paragraph").text().trim().split(" ");

and then encapsulate each word with the selected html, but that removes all other existing html the document might have

for (var it = 0; it < group_text.length; it++) {
    group_text[it] = $('<span/>', {
        id: 'word' + (it+1),
        html: group_text[it]
    }).append(" ");
}

Any solution that might actually work?

8
  • maybe you could explain what your goal is. Why do you need to wrap each word in your paragraph's text within span elements? Commented Dec 3, 2014 at 22:24
  • Could the element nesting go even deeper than what you've shown? This could get ugly fast. Commented Dec 3, 2014 at 22:24
  • @stevebot I need to know when I have clicked a word and the sequence of that word Commented Dec 3, 2014 at 22:34
  • @j08691 What do you propose? I am not sure what you mean.I need to interact with each word of a text (making it bold) without ruining any other formatting. Commented Dec 3, 2014 at 22:37
  • oohhh you should do not do it in that way... you can us $(event.target) Commented Dec 3, 2014 at 22:37

1 Answer 1

4

You will need to write recursive function to handle nested texts. Maybe something like this:

function wrap($node) {
    $node.contents().each(function() {
        if (this.nodeType === 3) {
            $(this).replaceWith(this.nodeValue.trim().split(/\s+/).map(function(el) {
                return '<span class="word' + ++i + '">' + el + '</span>';
            }));
        }
        else if (this.nodeType === 1) {
            wrap($(this));
        }
    });
}

var i = 0;
wrap($('#paragraph'));

alert($('#paragraph').html())
span {
    border-bottom: 1px dashed #AAA;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="paragraph"><a href="http://www.google.com">Google it!</a>But I <b>must</b> explain to you</p>

If node type is 3 then you need to split text into individual words and wrap each into span. If node type is 1, then this is element node, - call wrap function on it again.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.