innerHTML in DOM - javascript

I am unable to change the text inside my 'p' tag using this script
<script>
var firstItem = document.getElementByTagName('p');
firstItem.innerHTML = 'Adding Javascript';
</script>

You have several coding errors. Here's some corrected code:
<script>
var firstItem = document.getElementsByTagName('p')[0];
firstItem.innerHTML = 'Adding Javascript';
</script>
The correct method is document.getElementsByTagName('p'). Note the "s" at the end of "Elements".
Then, because document.getElementsByTagName('p') returns an HTML collection object, you have to either iterate over the collection or reach into the collection to grab a specific DOM object (which I did in my example with [0]).
And here's a working code snippet:
// change just the first <p> tag
document.getElementById("test1").addEventListener("click", function(e) {
var firstItem = document.getElementsByTagName('p')[0];
firstItem.innerHTML = 'Adding Javascript';
});
// change all the <p> tags
document.getElementById("test2").addEventListener("click", function(e) {
var items = document.getElementsByTagName('p');
for (var i = 0; i < items.length; i++) {
items[i].innerHTML = 'Setting All Items';
}
});
<button id="test1">Change text of first item</button><br><br>
<button id="test2">Change text of all items</button><br><br>
<p>This is some text</p>
<p>This is more text</p>
<p>This is and more text</p>

Related

how to avoid "undefined" inside a "for-loop" in javascript?

I'm changing the innerHTML with a for loop, but some values returns undefined since there's not the same amount of instances. How can I set up the loop to skip the empty instances?
This is to change the content of all instances with the same class, the amount of instances vary upon the class.
<!DOCTYPE html>
<html>
<body>
<p class="TEXT1">000</p>
<p class="TEXT1">000</p>
<p class="TEXT2">000</p>
<p class="TEXT3">000</p>
<p class="TEXT3">000</p>
<p class="TEXT3">000</p>
<p class="TEXT4">000</p>
<p class="TEXT5">000</p>
<p class="TEXT5">000</p>
<p class="TEXT5">000</p>
<p class="TEXT5">000</p>
<script>
function CHANGE() {
for (var i = 0; i < 10; i++) {
//"paragraphs" will be different content texts, not just the word with a number.
document.getElementsByClassName("TEXT1")[i].innerHTML = "Paragraph 1";
document.getElementsByClassName("TEXT2")[i].innerHTML = "Paragraph 2";
document.getElementsByClassName("TEXT3")[i].innerHTML = "Paragraph 3";
document.getElementsByClassName("TEXT4")[i].innerHTML = "Paragraph 4";
document.getElementsByClassName("TEXT5")[i].innerHTML = "Paragraph 5";
}
}
CHANGE();
</script>
</body>
</html>
The expected result is to get:
Paragraph 1
Paragraph 1
Paragraph 2
Paragraph 3
Paragraph 3
Paragraph 3
Paragraph 4
Paragraph 5
Paragraph 5
Paragraph 5
Paragraph 5
The actual result I get is:
Paragraph 1
Paragraph 1
Paragraph 2
Paragraph 3
000
000
Paragraph 4
Paragraph 5
000
000
000
Javascript Console:
Uncaught TypeError: Cannot set property 'innerHTML' of undefined
the amount of instances vary upon the class.
You could check the number of instances.
for (var el of document.getElementsByClassName("TEXT1"))
el.innerHTML = "Paragraph 1";
For multiple classes and texts:
let change = (cls, text) => {
for (var el of document.getElementsByClassName(cls))
el.innerHTML = text;
};
change('text1', 'paragraph 1');
change('text2', 'paragraph 2');
...
Inside your for loop check this condition
for(// your loop condition){
myVar = document.getElementsByClassName("TEXT")[i];
if (typeof myVar !== 'undefined'){
continue;
}
}
You shouldn't be trying to change all of the different categories of elements in one loop, nor should you be hardcoding the length of the loop or re-calculating the list of elements in every loop. Try this:
var text1Elements = document.getElementsByClassName("TEXT1");
for (var i = 0; i < test1Elements.length; i++) {
text1Elements[i].innerHTML = "Paragraph 1";
}
Then repeat that for every different class of element you want to manipulate. Alternatively, give all these elements an extra, common class, and just find and loop through the results for that, using a regular expression to determine the number. I'll include this example using ES6 syntax, since it's more complex anyway:
// Each element has the 'paragraph' class; for instance, class="TEXT1 paragraph", class="TEXT2 paragraph", etc.
const elements = document.querySelectorAll('.paragraph');
for (let element of elements) {
const matcher = element.className.match(/^TEXT(\d+)/i);
element.innerHTML = `Paragraph ${matcher[1]}`;
}
Every time you call document.getElementsByClassName, you are forcing the DOM to find and collect those elements. This makes for a slow web site. try something like this:
for (var i=1; i < 6; i++) {
var elements = document.getElementsByClassName("TEXT" + i);
for (var element of elements) {
element.innerHTML = "Paragraph " + i;
}
}
You are trying to iterate over indexes that are not present try this snippet:
function change() {
var classes = ['TEXT1', 'TEXT2', 'TEXT3', 'TEXT4', 'TEXT5'];
var paragraphs = ['Paragraph 1', 'Paragraph 2', 'Paragraph 3', 'Paragraph 4', 'Paragraph 5', ];
for (var i = 0; i < classes.length; i++) {
var elements = document.getElementsByClassName(classes[i]);
for (var j = 0; j < elements.length; j++) {
elements[j].innerHTML = paragraphs[i];
}
}
}
window.onload = function() {
change();
}
<!DOCTYPE html>
<html>
<body>
<p class="TEXT1">000</p>
<p class="TEXT1">000</p>
<p class="TEXT2">000</p>
<p class="TEXT3">000</p>
<p class="TEXT3">000</p>
<p class="TEXT3">000</p>
<p class="TEXT4">000</p>
<p class="TEXT5">000</p>
<p class="TEXT5">000</p>
<p class="TEXT5">000</p>
<p class="TEXT5">000</p>
</body>
</html>
You should instead start with the classNames and search for matching elements. Once you have these you can operate on them
function CHANGE() {
// define the classnames for TEXT1, TEXT2, ... TEXT6
for(let i=1;i<=6;i++){
let className = "TEXT"+i
// pickup the child elements with the matching class
let nodes = document.getElementsByClassName(className)
// change the text
for(let j=0; j<nodes.length;j++){
nodes[j].innerHTML="Paragraph "+i
}
}
}
Alternatively if you just wanted to work from a list of classnames you could say
function CHANGE() {
const classNames = ['TEXT1','TEXT2','TEXT3','TEXT4','TEXT5','TEXT6']
classNames.forEach(name=>{
let nodes = document.getElementsByClassName(name)
let innerText = "Paragraph "+name.replace("TEXT","")
for(let j=0; j<nodes.length;j++){
nodes[j].innerHTML=innerText
}
})
}

appending User entered text using createTextNode method

Right now I am trying to figure out how to append CREATED text to a CREATED p element depending on what a user enters into an input text field.
If I set the text after the createTextElement method, it displays just fine when I click the button. BUT what I want is: the user enters text in the input field and then upon clicking the button, the text get's added to the end of the div tag with the id of "mydiv". Any help is appreciated.
HTML:
<body>
<div id="mydiv">
<p>Hi There</p>
<p>How are you?</p>
<p>
<input type="text" id="myresponse">
<br>
<input type="button" id="showresponse" value="Show Response">
</p>
<hr>
</div>
</body>
JAVASCRIPT:
var $ = function(id) {
return document.getElementById(id)
}
var feelings = function()
{
$("myresponse").focus();
var mypara = document.createElement("p");
var myparent = $("mydiv");
myparent.appendChild(mypara);
var myText = document.createTextNode($("myresponse").value);
mypara.setAttribute("id", "displayedresponse");
mypara.appendChild(myText);
$("displayedresponse").appendChild(myText);
}
window.onload = function() {
$("showresponse").onclick = feelings;
}
You need to apply an argument to createTextNode function
You need to read the value of the input field so you can see the text.
Since you will reference mydiv on every click, i think moving mydiv variable to parent scope will suit you better
var $ = function (id) {
return document.getElementById(id)
}
let mydiv = $('mydiv');
$("showresponse").addEventListener('click', feelings);
function feelings() {
let textInput = $('myresponse').value;
var mypara = document.createElement("p");
var myText = document.createTextNode(textInput);
mypara.setAttribute("id", "displayedresponse");
mypara.appendChild(myText);
mydiv.appendChild(mypara);
$("displayedresponse").appendChild(myText);
}

How could I add the same string on different paragraph multiple time on the same HTML page?

I wish to know the best way to write only once the same thing and repeat inside the same page. For example:
<div>
<p id="description1"></p>
</div>
<div>
<p id="description1"></p>
</div>
--
I wish to write only one time the description1 inside the body. I think this could be achieved using the DOM.
Put the elements in the same class using the class attribute, then get the list of all elements using the getElementsByClassName() DOM function. You can then go over the list using a for loop.
[].forEach.call(document.getElementsByClassName("description"), function(elem) {
elem.innerHTML = "StackOverflow saved my day!";
});
You can even put the text in all elements of the same class using no JavaScript and only CSS by using the content attribute.
First of all, the ID field should be unique per element.
If you give all the tags a class <p class="description"></p> then you can use jQuery to set them all by calling:
$('.description').text('This is the text')
In javascript:
var elements = document.getElementsByClassName("description");
for (var i = 0; i < elements.length; i++) {
elements[i].innerHTML = "This is the text.";
}
Have a look at the solutions proposed here
How to repeat div using jQuery or JavaScript?
this one seems to work pretty well:
html:
<div id="container">data</div>
js:
var container = document.getElementById('container');
function block(mClass, html) {
//extra html you want to store.
return '<div class="' + mClass + '">' + html + '</div>';
}
// code that loops and makes the blocks.
// first part: creates var i
// second: condition, if 'i' is still smaller than three, then loop.
// third part: increment i by 1;
for (var i = 0; i < 3; i++) {
// append the result of function 'block()' to the innerHTML
// of the container.
container.innerHTML += block('block', 'data');
}
JSFIDDLE
Just added with a code by using
getElementsByClassName()
`<html>
<body>
<div class="example">First div element with class="example".</div>
<p class="example">Second paragraph element with class="example".</p>
<p>Click the button to change the text of the first div element with class="example" (index 0).</p>
<button onclick="myFunction()">Try it</button>
<p><strong>Note:</strong> The getElementsByClassName() method is not supported in Internet Explorer 8 and earlier versions.</p>
<script>
function myFunction() {
var x = document.getElementsByClassName("example");
for(var i=0;i< x.length;i++)
x[i].innerHTML = "Hello World!";
}
</script>
</body>
</html>`
If you wish to keep id, change your code like this :
script :
var pcount = 2// # p
var desc = document.getElementById('description1');
for(i=0; i<pcount;i++){
document.getElementById('description' + i).innerHTML = desc;
}
html
<div>
<p id="description1"></p>
</div>
<div>
<p id="description2"></p>
</div>
two elements cannot have same id but can have same class
<head>
<script>
var x = document.getElementsByClassName("description");
for (var i = 0; i < x.length; i++) {
x[i].innerHTML = "This is the text.";
}
</script>
<style>
.description1 { // this will apply the same style to all elements having class as description1
text-align: center;
color: red;
}
</style>
</head>
<body>
<div>
<p class="description1"></p>
</div>
<div>
<p class="description1"></p>
</div>
</body>
See the script tag. this solves your problem

Stack at getting elements with javascript

I have the following html elements from which I have to get some specific texts,
example "John Doe"
I'm a newbie in javascript but have been playing with getElementById etc but I can't seem to get this one right.
<div id="name">
<p><span id="nameheading">name: </span> John Doe</p>
</div>
Bellow is What I have tried:
function askInformation()
{
var nameHeading = document.getElementById("nameheading");
var paragraph = document.getElementsByTagName("p").item(0).innerHTML ;
var name = paragraph[4];
console.log(name); // prints letter (n)
}
I need help please
If you want to get the text following the span in the following:
<div id="name">
<p><span id="nameheading">name: </span> John Doe</p>
</div>
You can use something like:
// Get a reference to the span
var span = document.getElementById('nameheading');
// Get the following text
var text = span.nextSibling.data;
However that is highly dependent on the internal structure, it may be best to loop over text node children and collect the content of all of them. You may also want to trim leading and trailing white space.
You could also get a reference to the parent DIV and use a function like the following that collects the text children and ignores child elements:
// Return the text of the child text nodes of an element,
// but not descendant element text nodes
function getChildText(element) {
var children = element.childNodes;
var text = '';
for (var i=0, iLen=children.length; i<iLen; i++) {
if (children[i].nodeType == '3') {
text += children[i].data;
}
}
return text;
}
var text = getChildText(document.getElementById('name').getElementsByTagName('p')[0]);
or more concisely for hosts that support the querySelector interface:
var text = getChildText(document.querySelector('#name p'));
var paragraph = document.getElementsByTagName("p").item(0).innerHTML ;
var name = paragraph.replace('<span id="nameheading">name: </span>','').trim(); // John Doe

How to get innerHTML of DIV without few inside DIV's?

I have some DIV, what contains HTML with images, styles e.t.c. I want to remove exact div's that contains id = 'quot' or className = 'quote', but i don't understand how i can get not only innerHTML of each tag. For example, < p > and < /p > which don't have innerHTML also should be included in final parsed HTML.
var bodytext = document.getElementById("div_text");
var NewText = "";
if (bodytext.hasChildNodes){
var children = bodytext.childNodes;
for (var i = 0; i < children.length; i++){
if (children[i].id != "quot" && children[i].className != "quote" && children[i].innerText != ""){
NewText = NewText + children[i].innerHTML;
}
}
HTML of source need to be parsed:
<div id="div_text">
<p>
Some Text</p>
<p>
Some Text</p>
<p>
<img alt="" src="localhost/i/1.png" /></p>
<div id="quot" class="quote" />
any text <div>text of inside div</div>
<table><tr><td>there can be table</td></tr></table>
</div>
<p>
</p>
</div>
Desired output:
<p>
Some Text</p>
<p>
Some Text</p>
<p>
<img alt="" src="localhost/i/1.png" /></p>
<p>
</p>
Just grab a reference to the targeted divs and remove them from their respective parents.
Perhaps something a little like this?
EDIT: Added code to perform operation on a clone, rather than the document itself.
div elements don't have .getElementById method, so we search for an element manually.
window.addEventListener('load', myInit, false);
function removeFromDocument()
{
// 1. take car of the element with id='quot'
var tgt = document.getElementById('quot');
var parentNode = tgt.parentNode;
parentNode.removeChild(tgt);
// 2. take care of elements whose class == 'quote'
var tgtList = document.getElementsByClassName('quote');
var i, n = tgtList.length;
for (i=0; i<n; i++)
{
// we really should be checking to ensure that there aren't nested instances of matching divs
// The following would present a problem - <div class='quote'>outer<div class='quote'>inner</div></div>
// since the first iteration of the loop would also remove the second element in the target list,
parentNode = tgtList[i].parentNode;
parentNode.removeChild(tgtList[i]);
}
// 3. remove the containing div
var container = document.getElementById('div_text');
container.outerHTML = container.innerHTML;
}
function cloneAndProcess()
{
var clonedCopy = document.getElementById('div_text').cloneNode(true);
var tgt;// = clonedCopy.getElementById('quot');
var i, n = clonedCopy.childNodes.length;
for (i=0; i<n; i++)
{
if (clonedCopy.childNodes[i].id == 'quot')
{
tgt = clonedCopy.childNodes[i];
var parentNode = tgt.parentNode;
parentNode.removeChild(tgt);
break; // done with for loop - can only have 1 element with any given id
}
}
// 2. take care of elements whose class == 'quote'
var tgtList = clonedCopy.getElementsByClassName('quote');
var i, n = tgtList.length;
for (i=0; i<n; i++)
{
// we really should be checking to ensure that there aren't nested instances of matching divs
// The following would present a problem - <div class='quote'>outer<div class='quote'>inner</div></div>
// since the first iteration of the loop would also remove the second element in the target list,
parentNode = tgtList[i].parentNode;
parentNode.removeChild(tgtList[i]);
}
// 3. remove the containing div
//var container = clonedCopy; //.getElementById('div_text');
//container.outerHTML = container.innerHTML;
console.log(clonedCopy.innerHTML);
}
function myInit()
{
cloneAndProcess();
//removeFromDocument();
}

Categories

Resources