Change font after createTextNode() - javascript

I need to change the font of element created by the createTextNode() function:
var s = document.createTextNode(item.text);
s.setAttribute("font size") = -1;
elem.appendChild(s);
In my code I get error on Firebug:
s.setAttribute is not a function
How can I change a font of created element?

You don't specify font on text nodes, you do so on the parent element - in your case:
elem.style.fontSize = "20px";
If you don't wish to change the font size for the entire parent element, you can create a <span> element to wrap around the text node:
var span = document.createElement('span');
span.style.fontSize = "20px";
span.appendChild(s);
elem.appendChild(span);

createTextNode creates a Text node that has only one method: splitText. setAttribute is a method of the DOM Core that is implemented by the Element interface (i.e. not text nodes).
Generally, you should avoid setAttribute as it has numerous quirks and setting the related DOM property is faster and more reliable.
In any case, there is no "fontSize" attribute specified in HTML 4.01 for text nodes so you can't expect browsers to implement it. Text nodes inherit their style from their parent element, so if you want to set the font size of some text, wrap it in an element:
window.onload = function() {
var span = document.createElement('span');
// Set DOM property
span.style.fontSize = '200%';
span.appendChild(document.createTextNode('hey'));
// Add to document
document.body.appendChild(span);
};
But in general you are better off to define the style in a class and attach that to the span.

maybe you could use inline css. Never tried this with a textnode though
setAttribute('style', 'font-size:-1;');

Related

DOM: Adding empty element to DOM and page reflowing

I want adding elements to DOM while avoid page reflowing.
My questions:
var Span = document.createElement('span');
document.body.appendChild(Span);
// Span doesn't contain any child node
// and isn't setted or inherited any style
// so Span has width = height = 0
Will adding Span to DOM cause page reflowing?
// After adding Span to DOM,
// I need to add style and text to Span.
// In order to avoid page reflowing, I set style 'display:none' to Span.
Span.style.cssText = 'display:none;other:value';
Span.textContent = 'some text';
Can I use style.cssText property to set display:none and other css properties and avoiding page reflowing?
Or do I have to set style.display = none to avoid page reflowing first then use cssText to set other properties later?
Waiting for your advice and thanks for reading!
Adding or changing most things in the DOM will cause reflows. As suggested by commenters above, the best approach is to build the subtree of elements outside the DOM and then append it all at once:
var newDiv = document.createElement('div');
newDiv.style.someStyleProperty = 'someStyleValue'; // repeat as needed
newDiv.innerHTML = 'some tags and text';
document.body.appendChild(newDiv);
This will cause a single reflow, at the end when you call appendChild.

How to create new div dynamically, change it, move it, modify it in every way possible, in JavaScript?

I want to create new divs as the page loads. These divs will appear as an ordered group which changes depending upon external data from a JSON file. I will need to do this with a for loop because there are over 100 divs needed.
So, I need to be able to change each created div in regards to height, width, top/left and so on. Yet, document.getElementById("created_div").style.whatever does nothing, I can't even see a single new div appear. I've set the new divs height/width to 500px, background to "red", and so on, but no new divs are definitely appearing.
What am I doing wrong?
Creation var div = document.createElement('div');
Addition document.body.appendChild(div);
Style manipulation
Positioning div.style.left = '32px'; div.style.top = '-16px';
Classes div.className = 'ui-modal';
Modification
ID div.id = 'test';
contents (using HTML) div.innerHTML = '<span class="msg">Hello world.</span>';
contents (using text) div.textContent = 'Hello world.';
Removal div.parentNode.removeChild(div);
Accessing
by ID div = document.getElementById('test');
by tags array = document.getElementsByTagName('div');
by class array = document.getElementsByClassName('ui-modal');
by CSS selector (single) div = document.querySelector('div #test .ui-modal');
by CSS selector (multi) array = document.querySelectorAll('div');
Relations (text nodes included)
children node = div.childNodes[i];
sibling node = div.nextSibling;
Relations (HTML elements only)
children element = div.children[i];
sibling element = div.nextElementSibling;
This covers the basics of DOM manipulation. Remember, element addition to the body or a body-contained node is required for the newly created node to be visible within the document.
Have you tried JQuery? Vanilla javascript can be tough. Try using this:
$('.container-element').add('<div>Insert Div Content</div>');
.container-element is a JQuery selector that marks the element with the class "container-element" (presumably the parent element in which you want to insert your divs). Then the add() function inserts HTML into the container-element.

Remove all inline font related tags even if its within an inline style

I have a DOM, and in this DOM, I have loaded an entire webpage's HTML. I want to remove all font-related tags, even if its within a style tag.
Here's a pure Javascript function that'll convert any of a specified set of tags into a <span>:
function stripFonts(el, tags) {
if (el.tagName && el.tagName in tags) {
// replace the element with a span
var old = el, el = document.createElement('span');
old.parentNode.replaceChild(el, old);
// and move the children
while (old.hasChildNodes()) {
el.appendChild(old.firstChild);
}
}
// recursive test all of this node's children
var child = el.firstChild;
while (child) {
child.removeAttribute('style'); // NB: removes *all* style attributes
stripFonts(child, tags);
child = child.nextSibling;
}
}
var tags = { 'B': 1, 'FONT': 1, 'STRIKE': 1 };
demo at http://jsfiddle.net/alnitak/4fBRQ/
Using a <span> simplifies the code because it maintains the original DOM tree, and avoids the need to collapse adjacent text nodes together.
Adding extra tags to be stripped is trivial. It would need some additional work to handle font specific inline style tags, although removing every style attribute is easy, as shown here.
$("font").attr("face", "");
$("*").css("font", "");
You Can clear the fact attr of font element and clear font feom all css in DOM using jQuery

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).

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