carmina
carmina

Reputation: 317

Using replaceChild to change node

Let's say I have a node with nodeType = 3, and I want the word "good" to be wrapped by a span.

"good morning to you" //node
"<span>good</span> morning to you" //newnode

I tried to replace the old node with a new node using the following:

newNode = node.cloneNode();
newNode.nodeValue = "<span>good</span> morning to you";
node.parentNode.replaceChild(newNode, node);

But this doesn't work at all since I think the node has a nodeType of 3. The span tags are rendered as texts. I'm trying not to use jQuery in this case. Thank you.

Edit 1: To clarify, the node is a childNode of a contentEditable div:

<div contenteditable=true>good morning to you</div>

"good morning to you" is the childNode of the div, and for this instance a text node.

Upvotes: 0

Views: 1139

Answers (3)

C. S.
C. S.

Reputation: 813

So, this may be a bit RAW, but it get's the job done. What I found out is that you need to wrap the parent node to be some kind of element node, then you wrap a part of the text you want in the <span> in another node and append it to the parent, and finally you append the rest of the text node to the parent.

<script>
    var text1 = document.createTextNode("good");
    var text2 = document.createTextNode(" morning to you");
    var span = document.createElement("span");
    var parent = document.createElement("div");

    span.appendChild(text1);
    parent.appendChild(span);
    parent.appendChild(text2);

    // use debugger to go into each object
    debugger;
</script>

Here is my example if you would like to experiment:

Upvotes: 0

Andrew
Andrew

Reputation: 5340

Try disable the contentEditable firstly, replace the content, and then re-enable.

//disable contentEditable
ele.contentEditable=false;

//replace
ele.innerHTML = ele.innerHTML.replace(/good/i,'<span>good</span>');

//re-enable
ele.contentEditable=true;

http://jsfiddle.net/fLSht/1/

Upvotes: 0

Halcyon
Halcyon

Reputation: 57729

Yep, you're correct, this doesn't work.

Something like this should work:

var node = /* the textNode */
var spanEl = document.createElement("span");
var spanTextNode = document.createTextNode();
spanEl.appendChild(spanTextNode);
spanTextNode.nodeValue = "good";
node.nodeValue = " morning to you"
node.parentNode.insertBefore(spanEl, node);

As you can this gets a little involved. The DOM API is not the nicest.

You can reduce this a bit to:

var node = /* the textNode */
var spanEl = document.createElement("span");
spanEl.appendChild(document.createTextNode("good"));
node.nodeValue = " morning to you"
node.parentNode.insertBefore(spanEl, node);

You can also just say: f.ck it and use innerHTML

node.parentNode.innerHTML = "<span>good</span> morning to you";

Upvotes: 2

Related Questions