How to Change Only Text Node in Element

How to change only text node in element

If you use contents() method it will also return text nodes. Since jQuery doesn't have text node methods, convert last node to a DOM node

$('label[for="user_name"]').contents().last()[0].textContent='Title';

Demo: http://jsfiddle.net/yPAST/1/

jQuery way to replace just a text node with a mix of HTML and text?

You basically want to replace the first child (text node) with the new content. You need http://api.jquery.com/replaceWith/

// Text node we want to process and removevar textNode = $("#target").contents().first();// Break the text node upvar parts = textNode.text().split(/\s/);// Put links around themvar replaceWith = "";for (var i =0; i < parts.length;i++) {    replaceWith += "<a href='http://www.google.com'>"  + escapeHTML(parts[i]) + "</a> ";}// Replace the text node with the HTML we createdtextNode.replaceWith(replaceWith);
function escapeHTML(string) { return string.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><div id="target">example, handles escaping properly, you should see an ampersand followed by "amp;" here: &amp; <img src="/foobar.png"></div>

Change textNode value

If you have a specific node (of type #text) and want to change its value you can use the nodeValue property:

node.nodeValue="new value";

Note:

innerText (and possibly textContent) will return/set both the current node and all descendent nodes text, and so may not be the behaviour you want/expect.

Use javascript to change text only in an element

Get the first textNode by firstChild property and update the content.

function change_stuff() {  // get the first child node, in your code which is the text node  var t = document.getElementById('to_change').firstChild;
// update the text contents in the node t.nodeValue = "";
// or t.textContent = "";
// or remove the node itself // t.parentNode.removeChild(t)}
<div id="to_change">  This is a huge block of text that I want to replace while leaving the image in place  <img src="./the_image.jpg"></div><button onclick="change_stuff();">  ThE dOER!!</button>

Replace text in the middle of a TextNode with an element

To 'change' a text node into an element, you must replace it with an element. For example:

var text = tree.currentNode;
var el = document.createElement('foo');
el.setAttribute('bar','yes');
text.parentNode.replaceChild( el, text );

If you want to retain part of the text node, and inject an element "in the middle", you need to create another text node and insert it and the element into the tree at the appropriate places in the tree.


Edit: Here's a function that might be super useful to you. :)

Given a text node, it runs a regex on the text values. For each hit that it finds it calls a custom function that you supply. If that function returns a string, then the match is replaced. However, if that function returns an object like:

{ name:"element", attrs{onmouseover:"sendWord('foo')"}, content:"foo" }

then it will split the text node around the match and inject an element in that location. You can also return an array of strings or those objects (and can recursively use arrays, strings, or objects as the content property).

Demo: http://jsfiddle.net/DpqGH/8/

function textNodeReplace(node,regex,handler) {
var mom=node.parentNode, nxt=node.nextSibling,
doc=node.ownerDocument, hits;
if (regex.global) {
while(node && (hits=regex.exec(node.nodeValue))){
regex.lastIndex = 0;
node=handleResult( node, hits, handler.apply(this,hits) );
}
} else if (hits=regex.exec(node.nodeValue))
handleResult( node, hits, handler.apply(this,hits) );

function handleResult(node,hits,results){
var orig = node.nodeValue;
node.nodeValue = orig.slice(0,hits.index);
[].concat(create(mom,results)).forEach(function(n){
mom.insertBefore(n,nxt);
});
var rest = orig.slice(hits.index+hits[0].length);
return rest && mom.insertBefore(doc.createTextNode(rest),nxt);
}

function create(el,o){
if (o.map) return o.map(function(v){ return create(el,v) });
else if (typeof o==='object') {
var e = doc.createElementNS(o.namespaceURI || el.namespaceURI,o.name);
if (o.attrs) for (var a in o.attrs) e.setAttribute(a,o.attrs[a]);
if (o.content) [].concat(create(e,o.content)).forEach(e.appendChild,e);
return e;
} else return doc.createTextNode(o+"");
}
}

It's not quite perfectly generic, as it does not support namespaces on attributes. But hopefully it's enough to get you going. :)


You would use it like so:

findAllTextNodes(document.body).forEach(function(textNode){
replaceTextNode( textNode, /\b\w+/g, function(match){
return {
name:'element',
attrs:{onmouseover:"sendWord('"+match[0]+"')"},
content:match[0]
};
});
});

function findAllTextNodes(node){
var walker = node.ownerDocument.createTreeWalker(node,NodeFilter.SHOW_TEXT);
var textNodes = [];
while (walker.nextNode())
if (walker.currentNode.parentNode.tagName!='SCRIPT')
textNodes.push(walker.currentNode);
return textNodes;
}

or if you want something closer to your original regex:

  replaceTextNode( textNode, /(^|\W)(\w+)/g, function(match){
return [
match[1], // might be an empty string
{
name:'element',
attrs:{onmouseover:"sendWord('"+match[2]+"')"},
content:match[2]
}
];
});

How can I change an element's text without changing its child elements?

Mark’s got a better solution using jQuery, but you might be able to do this in regular JavaScript too.

In Javascript, the childNodes property gives you all the child nodes of an element, including text nodes.

So, if you knew the text you wanted to change was always going to be the first thing in the element, then given e.g. this HTML:

<div id="your_div">
**text to change**
<p>
text that should not change
</p>
<p>
text that should not change
</p>
</div>

You could do this:

var your_div = document.getElementById('your_div');

var text_to_change = your_div.childNodes[0];

text_to_change.nodeValue = 'new text';

Of course, you can still use jQuery to select the <div> in the first place (i.e. var your_div = $('your_div').get(0);).

How can I get only the content of text nodes (not nested tags) from an HTML tag element in JS?

You have a couple of options:

bob is in a Text node in the div. You can't select a Text node directly, but you can access it via the childNodes on its parent (or nextSibling on the span in front of it, etc.):

const div = document.getElementById("mydiv");
console.log("`nodeValue` of each text node in the div:");
for (const child of div.childNodes) {
if (child.nodeType === Node.TEXT_NODE) {
console.log(child.nodeValue);
}
}
<div id="mydiv">
<span>foo</span>
<span>bar</span>
bob
</div>

jQuery replace only the text of a node, ignoring current internal nodes

If you have access to the HTML I'd wrap the text in a span so that you can address it easily. However, with what you have so far you can simply iterate over all nodes in the element and change the textContent of the first text node (nodeType==3):

$(function(){        $("label").contents().each(function() {        if(this.nodeType == 3){            this.textContent = "Quick Search: ";            return false;        }    })    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><label>Search:  <input id="search-box" type="text"/></label>

Replace a textNode with HTML text in Javascript?

You'll need to replace the textNode with an HTML element, like a span, and then set your linkified-text as that element's innerHTML.

var replacementNode = document.createElement('span');
replacementNode.innerHTML = linkify(n.textContent);
n.parentNode.insertBefore(replacementNode, n);
n.parentNode.removeChild(n);


Related Topics



Leave a reply



Submit