3

I've come up short on an answer for this so hopefully there's someone who can help me.

I'm trying to non-destructively insert HTML before and after a substring or position in text to create new inline elements or wrap existing text. I would just use innerHTML and be done with this already but I would really like to preserve possible event listeners that might be bound to that particular DOMNode. Is there a method or a prototype of a Element that treats textNodes as individual items that would allow me to append HTML after or before it?

The code might operate like this:

var testParagraph = document.getElementById("TestParagraph");

/** 
    text nodes would represent each item 
    that has been seperated by a space, for example 
**/

testParagraph.insertBefore(document.createElement("span"), testParagraph.textNodes[3])

Thanks for your time!

2 Answers 2

2

If you want to insert dom elements into text, then there will not be an issue of event handlers since event handlers can not be bound onto the text itself. It's possible, and easier than you might think, to change the content of a DOM element without destroying any event handlers.

function insertAtStringPos(el, pos, insertable) {
    if(!el.children.length) {
        var text      = el.outerText;
        var beginning = document.createTextNode(text.substr(0, pos));
        var end       = document.createTextNode(text.substr(pos - text.length));

        while (el.hasChildNodes()) {
            el.removeChild(el.firstChild);
        }

        el.appendChild(beginning);
        el.appendChild(insertable);
        el.appendChild(end);
    }
}

Example: http://jsfiddle.net/9a8rxhp4/

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

6 Comments

..and a fork to show an element inserted with elements / text inside of it: jsfiddle.net/jxadjfeo
This is great! I wasn't able to get to get it to work in FireFox 47.0 as an FYI but on Chrome it worked just as your said. Thanks for your code sample!
Just as an aside, I've noticed that if there are HTML child elements in the container already, they are omitted from the replacement text. Is there a workaround for this?
I've just checked through some logs and apparently it's the document.createTextNode that's stripping the tags. Not sure if there's a workaround for that given that it's inherited in the function.
They would be omitted since el.outerText returns no HTML. You could replace line 3 with var text = el.outerHTML, although you will also need to ammend the document.createTextNode lines as outerHTML returns a string that createTextNode will not parse.
|
1

you can use the split() to split the text of the element.

var res = testParagraph.text().split(" ");
// each word is now in the res[0],res[1] ..
//and then you can create a textNode 
var textNode1 = document.createTextNode("before");
var textNode2 = document.createTextNode(res[0]); 

var spanElement = document.createElement("span");      
spanElement.appendChild(textNode1);
spanElement.appendChild(textNode2); 
//...   
//then return them into the testParagraph
testParagraph.appendChild(spanElement);

4 Comments

Thanks for your response. Would this method allow me to do the following however? Converting this string from: <div id="TestParagraph">Hello this is a test</div> into possibly this <div id="TestParagraph">Hello <span></span> this is a test</div> or even <div id="TestParagraph">Hello <span>this</span> is a test</div>?
Yes you can do this!You will create the span tags like the spanElement i created above and then you will insert it in the position that you want.
Great! Thanks a bunch for your code. I tried running it on a jsfiddle.net/rfdzgfqm (jsfiddle) but it's thrown an error. Maybe you're using a jQuery function for text()?
yes its a jquery function.You can use instead the innerHtml -> var x = document.getElementById("myP").innerHTML

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.