How to write to a <div> element using JavaScript? - javascript

I've searched around using Google and Stack Overflow, but I haven't seemed to find a answer to this. I want to write text inside a <div> element, using JavaScript, and later clear the <div> element, and write more text into it. I am making a simple text adventure game.
This is what I am trying to do:
<DOCTYPE!HTML>
<body>
<div class="gamebox">
<!-- I want to write in this div element -->
</div>
</body>
As a new user to JavaScript, how would I be able to write inside the div element gamebox? Unfortunately, my JavaScript skills are not very good, and it would be nice if you can patiently explain what happens in the code.

You can use querySelector to get a reference to the first element matching any CSS selector. In your case, a class selector:
var div = document.querySelector(".gamebox");
querySelector works on all modern browsers, including IE8. It returns null if it didn't find any matching element. You can also get a list of all matching elements using querySelectorAll:
var list = document.querySelectorAll(".gamebox");
Then you access the elements in that list using 0-based indexes (list[0], list[1], etc.); the length of the list is available from list.length.
Then you can either assign HTML strings to innerHTML:
div.innerHTML = "This is the text, <strong>markup</strong> works too.";
...or you can use createElement or createTextNode and appendChild / insertBefore:
var child = document.createTextNode("I'm text for the div");
div.appendChild(span); // Put the text node in the div
Those functions are found in the DOM. A lot of them are now covered in the HTML5 specification as well (particularly Section 3).

Select a single element with document.querySelector or a collection with document.querySelectorAll.
And then it depends, on what you want to do:
Writing Text into the div or create an Element and append it to the div.

Like mentioned getElementsByClassName is faster. Important to know it when you use this you get returned an array with elements to reach the elment you want you specify its index line [0], [1]
var gameBox = document.getElementsByClassName('gamebox')[0];
Here how you can do it
//returns array with elements
var gameBox = document.getElementsByClassName('gamebox');
//inner HTML (overwrites fsd) this can be used if you direcly want to write in the div
gameBox[0].innerHTML ='<p>the new test</p>';
//Appending when you want to add extra content
//create new element <p>
var newP = document.createElement('p');
//create a new TextNode
var newText = document.createTextNode("i'm a new text");
//append textNode to the new element
newP.appendChild(newText);
//append to the DOM
gameBox[0].appendChild(newP);
https://developer.mozilla.org/en-US/docs/Web/API/document.createElement
https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName

Related

What is the difference between textContent and a new text Node? [duplicate]

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.

Inserting div into existing div with class only

I'm trying to create a new div in Javascript with two spans in it, each containing a string of text. They are then meant to be inserted before div.two in div.inner.
The div I'm trying to insert it into only has a class and I cannot target it by any ID, unfortunately.
I have also created a codepen here: https://codepen.io/lisaschumann/pen/BXqJKY
Any help is massively appreciated!
HTML
<html>
<div class="inner">
<div class="one"></div>
<div class="two"></div>
</div>
</html>
JS
window.onload=function(){
var infobox = document.createElement("div");
infobox.classList.add('infobox');
var spanOne = document.createElement("div");
var spanOneText = document.createTextNode('Important text 1');
var spanTwo = document.createElement("div");
var spanTwoText = document.createTextNode('Important text 2');
spanOne.appendChild(spanOneText);
spanTwo.appendChild(spanTwoText);
infobox.appendChild(spanOne);
infobox.appendChild(spanTwo);
var targetDiv = document.getElementsByClassName("inner");
targetDiv.insertBefore(infobox, targetDiv.childNodes[1]);
}
Errors:
Cannot read property '1' of undefined
at window.onload
The main issue is that getElementsByClassName returns a live collection of nodes rather than one node and so you would need to access the correct node in that list similar to an array: targetDiv[0], perhaps.
The easier method is to use querySelector to grab the element you want using its class, for example:
var parent = document.querySelector(".inner");
var two = document.querySelector(".two");
parent.insertBefore(infobox, two);
But! there's even a shortcut method you can use here that allows you to add an HTML string direct to the DOM which might save you a bit of time, and some code.
// Create the HTML
const html = `
<div>
<span>Text alpha</span>
<span>Text beta</span>
</div>`;
// Grab the element containing your "two" class
const two = document.querySelector('.inner .two');
// Using insertAdjacentHTML to add the HTML before the two element
two.insertAdjacentHTML('beforebegin', html);
<div class="inner">Inner
<div class="one">one</div>
<div class="two">two</div>
</div>
insertAdjacentHTML
This doesn't work because of these lines
var targetDiv = document.getElementsByClassName("inner");
targetDiv.insertBefore(infobox, targetDiv.childNodes[1]);
document.getElementsByClassName returns a NodeList. targetDiv.childNodes is undefined, because childNodes doesn't exist on a NodeList.
You need to either use a list operation like Array.prototype.forEach, change getElementsByClassName to getElementByClassName (note the s) or access the first node in the node list using the array indexer syntax.
I assume you meant to do something like this:
var targetDiv = document.getElementByClassName('inner')
targetDiv.insertBefore(infobox, targetDiv.childNodes[1])
This will insert a node in between the first and second child of the first DOM node with the class inner.
Try this out , targetDiv is an array by default due to the getElementsByClassName method , even though it has a single element.Hence you need to specify the index i.e. 0 ( as it's the first element of the array)
var targetDiv = document.getElementsByClassName("inner")[0]; targetDiv.insertBefore(infobox, targetDiv.children[1]); }
Using JQuery
$(document).ready(function(){
$(`<div>Important text 1<span></span>Important text 2<span></span></div>`).insertBefore( ".inner .two" );
)
I would encourage you to use JQuery and then shift to vanilla javascript later on. You can do simple tasks like this in just few lines of code and it is also easily debuggable because of that

<br> not being appended to div

ogres = document.getElementById('${contentID}')
.
let prettify = streamArray[streamArray.length - 1].split(/--/),
layers = document.createTextNode(prettify[0]),
onions = document.createTextNode(prettify[1]),
breaking = document.createElement('br');
I have an array of two elements that I've created called prettify.
I have definitely confirmed that the prettify[0] and prettify[1] are the elements I want so I make them into onions and layers which are text nodes to be appended to the div.
You'll note I also have breaking which is a break element I create and also append to the div.
I then have the div, orges.
Now for some unknown reason when I do this:
ogres.appendChild(layers);
ogres.appendChild(breaking);
ogres.appendChild(onions);
ogres.appendChild(breaking);
on the html page, this is created:
layersonions
<br>
1: why is this happening
2: how do I fix it?
3: no I don't plan on keeping these variable names, but they are fun :3
When you use document.createElement('br'); to create an element, it is appended as the second node of the parent.
Since you are using the same reference again, it simply detaches the existing element and appends it again in the new position.
It is a single reference to the element. To fix it you will have to create and append an element on the fly.
ogres.appendChild(layers);
ogres.appendChild(document.createElement('br'));
ogres.appendChild(onions);
ogres.appendChild(document.createElement('br'));
appendChild
If you still want to use the variable reference then you could use the cloneNode method which will clone the existing node before insertion.
ogres.appendChild(layers);
ogres.appendChild(breaking);
ogres.appendChild(onions);
ogres.appendChild(breaking.cloneNode(false));
cloneNode

Native Javascript doesn't append element on the DOM

I have a website built in Expression Engine. In the back-end there is a code snippet that takes care of a JavaScript request and build a page based on the request.
I have a HTML Page without head tag.
This page is without styling
Sample:
<div class="top-arrow"><p><!--- Rest of code --></p>
</div>
<!-- Html page continues-->
I have added the following code in my attempt and it doesnt seem to work.
var span = document.createElement("span"); //Test element
span.textContent = "A <span> element.";
var node = document.getElementsByClassName("top-arrow");
node.insertBefore(span);
Below is what I get:
TypeError: node.insertBefore is not a function
node.insertBefore(span);
How best can I append text before the div with plain JavaScript.
getElementsByClassName will return array-like node-list which does not have method insertBefore
The Node.insertBefore(newNode, referenceNode) method inserts the specified node before the reference node as a child of the current node(If referenceNode is null, the newNode is inserted at the end of the list of child nodes)
Note: referenceNode is not an optional argument, if there is no ant ref node, pass null
Try this:
var span = document.createElement("span");
span.textContent = "A <span> element.";
var node = document.getElementsByClassName("top-arrow")[0];
//_____________________________________________________^^(Get the first element from collection)
node.insertBefore(span, null);
<div class="top-arrow">
<p>
</p>
</div>
document.getElementsByClassName("top-arrow") will return a live HTMLCollection. You can use it like an array:
node = document.getElementsByClassName("top-arrow")[0];
Also, if you want the new node to appear before top-arrow you need to do:
node.parentNode.insertBefore(span, node);
As it is node has no children, so there is no need to do insertBefore.
Even though your HTML code has no body and head, the browser will 'fix' your HTML and add one.
I would write your code like this:
var span = document.createElement("span"); //Test element
span.appendChild(document.createTextNode("A <span> element."));
var node = document.getElementsByClassName("top-arrow")[0];
node.parentNode.insertBefore(span, node);
Function getElementsByClassName() returns an array containing nodes with class specified. If you want to insertBefore or append anything to it you need to specify index of an element in this array. Also, insertBefore requires two arguments in function call (elementToInsert, elemenBeforeWhichYouWantToInsert). So, something like this should work:
document.getElementsByClassName('top-arrow')[0].insertBefore(element, beforeWhatToInsert);
Thank you guys for all your input they are very informative. I have solved this without the need of manipulating my DOM element by simply copying the dynamic part of the page and actually creating a new template in the back-end of Expression Engine and my problem was solved.

javascript elements/tags array DOM node access

what's the different between using:
// assuming using elements/tags 'span' creates an array and want to access its first node
1) var arrayAccess = document.getElementsByTagName('elementName')[0]; // also tried property items()
vs
// assuming I assign an id value to the first span element/tag
// specifically calling a node by using it's id value
2) var idAccess = document.getElementById('idValue');
then if I want to change the text node....when using example 1) it will not work, for example:
arrayAccess.firstChild.nodeValue = 'some text';
or
arrayAccess.innerText/innerHTML/textContent = 'some text';
If I "access" the node through its id value then it seems to work fine....
Why is it that when using array it does not work? I'm new to javascript and the book I'm reading does not provide an answer.
Both are working,
In your first case you need to pass the tag name instead of the element name. Then only it will work.
There might be a case that you trying to set input/form elements using innerHTML. At that moment you need to use .value instead of innerHTML.
InnerHTML should be used for div, span, td and similar elements.
So your html markup example:
<div class="test">test</div>
<div class="test">test1</div>
<span id="test">test2</span>
<button id="abc" onclick="renderEle();">Change Text</button>
Your JS code:
function renderEle() {
var arrayAccess = document.getElementsByTagName('div')[0];
arrayAccess.innerHTML = "changed Text";
var idEle = document.getElementById('test');
idEle.innerHTML = "changed this one as well";
}
Working Fiddle
When you use document.getElementsByTagName('p'), the browser traverses the rendered DOM tree and returns a node list (array) of all elements that have the matching tag.
When you use document.getElementById('something'), the browser traverses the rendered DOM tree and returns a single node matching the ID if it exists (since html ID's are unique).
There are many differences when to use which, but one main factor will be speed (getElementById is much faster since you're only searching for 1 item).
To address your other question, you already have specified that you want the first element in the returned nodeList (index [0]) in your function call:
var arrayAccess = document.getElementsByTagName('elementName')[0];
Therefore, arrayAccess is already set to the first element in the returned query. You should be able to access the text by the following. The same code should work if you used document.getElementById to get the DOM element:
console.log(arrayAccess.textContent);
Here's a fiddle with an example:
http://jsfiddle.net/qoe30w2w/
Hope this helps!

Categories

Resources