TextNode or textContent? - javascript

What's the advantage of creating a TextNode and appending it to an HTML element over setting directly its textContent?
Let's say I have a span.
var span = document.getElementById('my-span');
And I want to change its text. What's the advantage of using :
var my_text = document.createTextNode('Hello!');
span.appendChild(my_text);
over
span.textContent = 'hello';

It 's not really matter of advantage but of proper usage depending on the need.
The fundamental difference is that:
createTextNode() is a method and works just as its name says: it creates an element... then you must do something with it (like in your example, where you append it as a child);
so it is useful if you want to have a new element and place it somewhere
textContent is a property you may get or set, with a unique statement and nothing else;
so it is useful when you only want to change the content of an already existing element
Now in the precise case of your question, you said you want to change the text of the element...
To be more clear say you have the following HTML element:
<span>Original text</span>
If you're using your first solution:
var my_text = document.createTextNode('Hello!');
span.appendChild(my_text);
then it will end with:
<span>Original textHello!</span>
because you appended your textNode.
So you should use the second solution.

Related

Get text inside parent div

I'm trying to get a text from an element, which isn't the first parent of the string. i.e.
<div id="wrp">
<h1>
this is the text I want
</h1>
</div>
let's say I got the div parent by element=document.getElementById("wrap") and now I want to get it's final text without looking inside all it's children : h1 and a. just the text that I see on the site.
Is it possible? Please show me an example.
You can use both innerText or textContent, but innerText doesn't works on Firefox. So, a crossbrowser solution:
var text = element.innerText || element.textContent;
JSBin. Interesting comparision about them.
You want to chain your queries so that you get the anchor tag after you get the wrap div (assuming you will never add more divs inside the anchor tag, which would be a bit weird):
var wrap = document.getElementById("wrap");
var text = wrap.getElementsByTagName("a")[0].innerHTML;
If you take a look at the Mozilla article it has more examples on how to do this. Alternatively there is textContent but since you stated that you might add more elements at a later date, if they have text in them too then you end up needing to refactor:
var wrap = document.getElementById("wrap");
var text = document.getElementById("wrap").textContent;

Add an id to a dynamically created element

I'm trying to add an id to an element that I create dynamically using javascripts' document.createElement() method. Basically I want to create an iframe in my html document and at the same time give that newly created element an id.
Here's my code so far. I've figured out how to put the element in the DOM and all that, i just need the id.
function build(content){
var newIframe = document.createElement("iframe");
var newContent = document.createTextNode("Hello World!");
newIframe.appendChild(newContent);
var element = document.getElementById("container");
document.body.insertBefore(newIframe, element);
document.getElementsByTagName("iframe").id = "active";
};
As you can probably see, I have tried to give it an id at the very end. Problem is, it doesn't work.
So if anyone has any idea of what is wrong here, or an alternative way of doing what I want to do, please feel free to express yourself. Many thanks!
Just add an attribute (id is an attribute) to that element directly, like this:
var newIframe = document.createElement("iframe");
newIframe.id = 'active';
... although it looks quite strange to have id equal to active (too generic for a unique identifier).
Your current approach doesn't work because document.getElementsByTagName("iframe") returns a collection of elements - NodeList or HTMLCollection (it's browser-dependant). While you can assign a value to its id property, it won't do what you mean to. To make it work, you can adjust it this way:
document.getElementsByTagName("iframe")[0].id = "active";
... but, as shown above, there's a better way.
newIFrame.setAttribute("id", "something");

Javascript - div content without innerHTML

I wanted to ask how to change div content, but not using innerhtml.
DEMO: http://jsfiddle.net/Cb6ME/
// get the div
var div = document.getElementById('foo');
// remove child nodes while at least one exists
while( div.childNodes[0] ) {
div.removeChild( div.childNodes[0] );
}
// create a new span element
var span = document.createElement( 'span' );
// give it some text content
span.appendChild( document.createTextNode("I'm new!!!") );
// append the span to the original div
div.appendChild( span );
You can use nodeValue to access the value of a node, however the value of a div. In your example you might have the following HTML...
<div id="myLovelyDiv">This is the text that you want to change</div>
and this script...
var myDiv = getElementById("myLovelyDiv");
myDiv.childNodes[0].nodeValue = "The text has been changed.";
but I fail to see why you wouldn't use
myDiv.innerHTML = "The text has been changed properly.";
A DIV element is a generic block level (by default) element in HTML used as a structural container to hold one or more block or inline elements.
Depending on what it is you want to change you can either select the sub-node in question directly, loop over the childNodes property to find the desired sub-node or completely rewrite the contents as html using innerHTML (which you stated you didn't want to do).
If you want to add content you can create a new element and use the appendChild(child) method of the DIV element to add to it's contents.
Is that what you were looking for?
I know I'm late but .textContent can be replaced for .innerHTML (if you only want to change the text and not code HTML).

Add text before or after an HTML element

If i have an HTML element like <div> with some text inside or another elements can I add before or after this div some text data without an html element, just plain text?
I'd like to use only pure Javascript.
Something like :
<div id="parentDiv">
my text must be added here
<div id="childDiv"></div>
</div>
Yes, you can create a text node with document.createTextNode('the text')
Then you can insert it like an element, with appendChild or insertBefore.
Example that insert a text before #childDiv:
var text = document.createTextNode('the text');
var child = document.getElementById('childDiv');
child.parentNode.insertBefore(text, child);
Just for the record:
div.insertAdjacentHTML( 'beforeBegin', yourText );
where div is your child-DIV.
Live demo: http://jsfiddle.net/ZkzDk/
If you just need text, I find that element.insertAdjacentText(position, text) is flexible for many scenarios and is also compatible with older browsers like IE6. Where position is exactly where you want the text to be and text is the text node or just a string. The options are:
'beforebegin' Before the element itself.
'afterbegin' Just inside the element, before its first child.
'beforeend' Just inside the element, after its last child.
'afterend' After the element itself.
Like this:
let div = document.getElementById('parentDiv');
div.insertAdjacentText('afterbegin', 'My Plain Text..');
In regards to the topic and the users question for inserting before or after, here is an example for after:
var text = document.createTextNode("my text must be added here.");
var childTag = document.getElementById("childDiv");
childTag.parentNode.insertBefore(text, childTag.nextSibling);
If the childTag does not have any siblings, it is okay because the insertBefore method handles this case and simply adds it as the last child.
Also can possibly use the appendChild() method after creating text node then add your childTag via the parentNode.
You can add text node. Create node - document.createTextNode('text') and then insert/append/replace - do whatever you want.
Something like this should do it:
<script type="text/javascript">
var parent = document.getElementById('parentDiv');
var sibling = document.getElementById('childDiv');
var text = document.createTextNode('new text');
parent.insertBefore(text, sibling);
</script>

Javascript: How to change a nodes name?

For example I have this HTML:
<body>
<div>Text</div>
</body>
And I would like to change the div to something else like p.
This is what I have tried but doesn't works:
var div = document.getElementsByTagName("div")[0]; // Get Element
div.nodeName = "p"; // Change It's Node Name to P
Please no libraries, and I don't really want to replace the actual div with a new p :)
You cannot just change an element. You have to create a new one. E.g.:
var div = document.getElementsByTagName("div")[0];
var p = document.createElement('p');
p.innerHTML = div.innerHTML;
div.parentNode.replaceChild(p, div);
But this could lead to invalid markup, if the original element contains nodes that cannot be descendants of the new node.
Reference: document.createElement, Node.replaceChild
Note: A better version (because it doesn't depend on serializing DOM to text and back and preserves attributes), can be found at https://stackoverflow.com/a/8584158/218196 .
The reason you can't just change the tagName property is because different HTML tags are actually different classes of objects. A div tag is an HTMLDivElement instance, a p tag is an HTMLParagraphElement instance, and so on. These classes can have vastly different properties and interfaces, so turning one into another is not as trivial as you'd think.
You can't.
As the MDC docs say:
nodeName is a read-only attribute.
You'll have to create a new element and give it the right content and attributes.
You cannot. The propery you're after is tagName, but it is read only. You would instead have to create a new node of the desired type, then transfer the innerHTML (and any other properties like className or style) to the new node. Then, insert the new node into the old node's parent, then remove the old node (or use replaceChild).
In other words, the long road is the only road.
I solved this in an XML scenario (eg. where there is no innerHTML) like so:
function renameNode (node, newNodeName) {
const newNode = node.ownerDocument.createElement(newNodeName);
Array.from(node.attributes).forEach(attr => newNode.setAttribute(attr.localName, attr.value));
Array.from(node.childNodes).forEach(childNode => newNode.appendChild(childNode));
node.parentElement.insertBefore(newNode, node);
node.parentElement.removeChild(node);
}
Does not return anything, but will update your DOM.

Categories