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 do you change an element innerText without changing its children
Try this:
document.getElementById("el1").childNodes[0].textContent = "changed";
<div id="el1">Change only me<div>but not me</div></div>
change text of an element without changing child elements
In order to access the text part, you need to use .contents()
See this answer and comments for more info.
$("#x").append("<b> pressed</b>") .contents().filter(function(){return this.nodeType == 3;}).first() .replaceWith("well done");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div id='x'>Press</div>
How do you remove text without affecting child elements?
Whit Javascript
you can just get all the childNodes of the element with id=parent
and then traverse these childs to .remove() those that have nodeType equal to Node.TEXT_NODE:
let childs = document.getElementById("parent").childNodes;childs.forEach(c => c.nodeType === Node.TEXT_NODE && c.remove());
<div id="parent"> <div>keep this</div> <div>keep this</div> Some random text that can't be predicted (to be removed) <div>keep this</div></div>
Proper way to change a SVG text without changing its children tspan
"Is there a property or any other method to specifically change the text content only?"
No, probably not. In fact, I think it might be for the better that such a method doesn't exist. Say for example that your <text>
node looked like this:
<text>
Foo
<tspan>Bar</tspan>
Baz
</text>
And now we would call the unknown method to change the text into Hello world
. What would the desired outcome be?
<text>
Hello world
<tspan>Bar</tspan>
</text>
<text>
<tspan>Bar</tspan>
Hello world
</text>
or even
<text>
Hello
<tspan>Bar</tspan>
world
</text>
Looking at it like this, it becomes clear that the "text content" can't be seen as a special case that exists apart from the node tree: just like the <tspan>
in your example, there can be multiple text nodes in any order and quantity. It's therefore hard to justify a special method that only changes text nodes, without introducing method to only change all the <tspan>
, <div>
and so on as well.
Solutions
If you regard all the text nodes as some kind of typeless elements like this:
<text>
<text>Foo</text>
<tspan>Bar</tspan>
<text>Baz</text>
</text>
there is little question about how you would approach targeting and changing your desired element. Options include:
- Grab it by index (like you already did). Judging from the fictional snippet above, it would be pretty safe to assume that
Foo
will indeed always be the first element. But just like with the:first
selector in CSS, you might rather not want to depend so rigidly on a specific structure. - A
class="text"
attribute would be very clear, but then you'd need to wrap your text in an actual element (which might be the best solution, but I'm following your specs here). - Grab the first element that is of the right type, just like you would with any other element.
The snippet below would therefore be a perfectly valid way to alter the first text node in a list of children (written in a functional manner to keep it concise).
Array.from(document.querySelector("text").childNodes)
.find(e => e.nodeType === Node.TEXT_NODE)
.textContent = "New Foo";
<svg>
<text x="10" y="30">
Foo Bar Baz
<tspan x="30" dy="30">FooBar</tspan>
<tspan x="30" dy="30">FooBaz</tspan>
</text>
</svg>
Update text of HTMLElement without affecting child elements
You could wrap the text in its own container, which is probably the best pattern here.
$('.text-content').text('Something else')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><span class="js-my-parent-span"> <span class="text-content">Hello, World!</span> <span class="js-my-child-span">Other content</span></span>
How to change text inside a div without changing any other element in the div
With element.innerText() you're essentially overwriting the whole content of your div - including other html elements such as the anchor tag.
There's a child attached to your div that actually holds your text.
You can reference it via document.getElementById("title").firstChild along with it's .data property.
function changeText(text) { document.getElementById("title").firstChild.data = text;}const button = document.getElementById('button');button.addEventListener('click', () => changeText('the new text I want '));
<div class="title" id='title'>Text I want to change <a href="https://link.com" target=_blank><img src="icon.svg" id='icon'></a></div>
<button id='button'>click here to change text<button>
Related Topics
Which "Href" Value Should I Use For JavaScript Links, "#" or "JavaScript:Void(0)"
How to Clear the Canvas For Redrawing
How to Retrieve an HTML Element'S Actual Width and Height
Determine If an HTML Element'S Content Overflows
Vue.Js Dynamic Images Not Working
How to Get the Entire Document HTML as a String
Difference Between Relative Path and Absolute Path in JavaScript
How to Show Page Loading Div Until the Page Has Finished Loading
Check With Jquery If Div Has Overflowing Elements
JavaScript - Append HTML to Container Element Without Innerhtml
How to Get the Element Clicked (For the Whole Document)
Animate Element to Auto Height With Jquery
When Is Nodelist Live and When Is It Static
How to Prevent Iframe from Redirecting Top-Level Window
How to Set the Form Action Through JavaScript
Force a Browser to Save File as After Clicking Link
Jquery: Simulating a Click on a ≪Input Type="File" /≫ Doesn't Work in Firefox