Easiest way to display childNodes NodeList? (Beginner) - javascript

I'm attempting to navigate the DOM tree and retrieve html comments and display them in alert box. This is as far as I can get, my alert box keeps returning empty. How do I properly display a nodeList array? I've searched for hours and cant seem to find any info that makes sense.
<!DOCTYPE html>
<html>
<head>
<title>Hidden Comments</title>
<h1 style="text-align:center">Hidden Comments</h1>
<script>
function concatComs(){
var c=document.getElementById('body');
var array=[];
for(var i=0;c.childNodes.length<i;i++){
if(c.childNodes[i].nodeType==8) array[i]=c[i];
}
alert(array.toString());
}
</script>
</head>
<body id="body" style="text-align: center">
<!--you-->
<h2>Find the hidden comments!</h2>
<p>Look closely and you'll find them!</p><!--found-->
<input type="button" value="Go!" onClick="concatComs()"/>
<!--them-->
</body>
</html>

Your for loop should start like:
for(var i=0; i < c.childNodes.length; i++){
Additionally, you probably want to add c.childNodes[i] to your array.
function concatComs(){
var c = document.getElementById('body');
var array=[];
for(var i=0; i < c.childNodes.length; i++){
if(c.childNodes[i].nodeType==8) {
array.push(c.childNodes[i]);
}
}
var result = "";
for(i in array) {
result += array[i].textContent + " ";
}
document.write(result);
}
<div id="body" style="text-align: center">
<!--you-->
<h2>Find the hidden comments!</h2>
<p>Look closely and you'll find them!</p><!--found-->
<input type="button" value="Go!" onClick="concatComs()"/>
<!--them-->
</div>

You can select comment strings with a regex expression like this
match(/<!--.*?-->/g)
then you can trim the first 4 and last 3 letter for each string
substr(4,comments[i].length-7)
Final result is like this
<!DOCTYPE html>
<html>
<head>
<title>Hidden Comments</title>
<script>
function concatComs(){
var comments = document.body.innerHTML.match(/<!--.*?-->/g);
for (var i = 0; i < comments.length; i++)
comments[i] = comments[i].substr(4,comments[i].length-7);
alert(comments);
}
</script>
</head>
<body id="body" style="text-align: center">
<h1 style="text-align:center">Hidden Comments</h1>
<!--you-->
<h2>Find the hidden comments!</h2>
<p>Look closely and you'll find them!</p><!--found-->
<input type="button" value="Go!" onClick="concatComs()"/>
<!--them-->
</body>
</html>
btw you should place your h1 tag inside the body not head.

Related

how to display numbers of value in HTML?

Few days ago I've written some JavaScript about getting some data from JSON and it successfully output on console.log.
Now I want to output values on a HTML document, try to do with a button which can refresh the data ( like I click it it request again and get new data).
The problem I facing now is , I need to output numbers of data on one line.
OUTPUT EXAMPLE:(Time), (URL), (views)Line 1 20200406 , www.XXX.com , 2000
Line 2 20200406 , www.YYY.com , 5000
Line 3 20200406 , www.YZZ.com , 9000
if I using
document.getElementById("p2").innerHTML = String({a,b,c}) ;
it only output var c
Will it be better if i use textarea ?
Thankyou.
var a='';
var b='';
var c='';
function clickme() {
for(var i=0; i<3 ;i++){
a=a++;
b=b++;
c=+b;
document.getElementById("p2").innerHTML = String({a,b,c}) ;
}
}
<!DOCTYPE HTML>
<HTML>
<head>
<title>Check UAT4 & UAT8 Version</title>
<link rel="stylesheet" type="text/css" href="test.css">
<script src="test.js"></script>
</head>
<body>
<div id="test">
<button type="button" onClick="clickme()">Click to Test</button>
<p id= "p1" >testing</p1>
<p id= "p2" >2222222</p2>
</div>
</body>
</HTML>
Use JSON.stringify({a,b,c}) instead of String({a,b,c})
var a=0, b=0, c=0;
function clickme() {
let htmlString ='';
for(var i=0; i<3 ;i++){
a++;
b++;
c=+b;
htmlString = htmlString + JSON.stringify({a,b,c}) + '<br>'
}
document.getElementById("p2").innerHTML =htmlString ;
}
<body>
<div id="test">
<button type="button" onClick="clickme()">Click to Test</button>
<p id= "p1" >testing</p1>
<p id= "p2" >2222222</p2>
</div>
If you want multiple nodes you have to create them and append to your div.
Do something like following to output 3 (or n) lines in div:
var a='', b='', c='';
function clickme() {
for(var i=0; i<3 ;i++){
a=a++;
b=b++;
c=+b;
var el = "p"+(i+2)
var node = document.createElement("p");
var textnode = document.createTextNode(JSON.stringify({a,b,c}));
node.appendChild(textnode);
document.getElementById("test").appendChild(node);
}
}
<body>
<div id="test">
<button type="button" onClick="clickme()">Click to Test</button>
<p id= "p1" >testing</p>
<p id= "p2" >2222222</p>
</div>

document.getElementsByClassName(variables);

I'm trying to target an element through the use of two variables. I know how to do this for id's, but what I'm doing for classes doesn't seem to works. Does anyone have an idea what I'm doing wrong?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
var colour = purple;
var number = 1;
function check() {
var x = document.getElementsByClassName(colour number);
x[0].innerHTML = "Hello World!";
}
</script>
</head>
<body>
<div>Username: </div>
<input id="test" type="text" onblur="check()">
<div class="1 purple">one</div>
<div class="2 red">two</div>
<div class="3 blue">three</div>
<div class="4 brown">four</div>
<div class="5 orange">five</div>
<div class="6 yellow">six</div>
<div class="7 white">seven</div>
</body>
</html>
Update
I've tried both options but neither seems to work. This is the updated script.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
function check() {
var colour = purple;
var number = one;
//var x = document.getElementsByClassName(colour + ' ' + number);
var x = document.querySelector('.' + colour + '.' + number);
x[0].innerHTML = "Hello World!";
}
</script>
</head>
<body>
<input id="test" type="text" onblur="check()">
<div class="one purple">one</div>
<div class="two red">two</div>
<div class="three blue">three</div>
<div class="four brown">four</div>
<div class="five orange">five</div>
<div class="six yellow">six</div>
<div class="seven white">seven</div>
</body>
</html>
Also note, this is only a test script. Once I get it working, I'll add a lot more divs, one for each color/number combination, so selecting on one class will not work.
The expression colour number is not a valid expression.
To specify the class names you need a string with space separated class names, for example "purple 1". Concatenate the strings with a space between them:
var x = document.getElementsByClassName(colour + ' ' + number);
However, as both the colors and numbers are unique, you only need to look for one of them:
var x = document.getElementsByClassName(colour);
or:
var x = document.getElementsByClassName(number);
Note: Class names that are only digits may be problematic in some situations. It's recommended that a class name doesn't start with a digit.
You should construct a string:
var colour = 'purple';
var number = 1;
var x = document.querySelector('.'+colour+'.'+number);

Taking the values of two same element

In console if I type this command:
document.querySelectorAll('div.information div.contact div ')[1]
The result I take is
<span class="information">
<call>number 1</call>
<call>number 2</call>
</span>
How can I take the innerHTML of call element? Should I use the nth child?
Result:
number 1
and after another command
number 2
Try this,
HTML
<span class="information">
<call>number 1</call>
<call>number 2</call>
</span>
JavaScript
var values = [];
var elements = document.getElementsByTagName('call');
for (var i = 0; i < elements.length; i++) {
values.push(elements[i].innerHTML);
}
/** ["number 1", "number 2"] **/
console.log(values);
Example
JSFiddle
There's no "call" element.
document.getElementsByClassName() is probably more appropriate in this case, but using an ID would be even easier.
window.onload = function() {
var information = document.getElementsByClassName('information')[0]
var calls = document.getElementsByClassName('call');
var numbers = [];
for (var i = 0; i < calls.length; i++) {
numbers.push(calls[i].innerHTML);
}
for (var i = 0; i < numbers.length; i++) {
document.getElementById('numbers').value += numbers[i] + '\n';
}
}
<span class="information">
<span class="call">number 1</span>
<span class="call">number 2</span>
</span>
<h2>Added so we can see something without looking at the console:</h2>
<form name="form" id="form">
<textarea id="numbers"></textarea>
</form>
<html>
<head>
<title>
Practice
</title>
</head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var data = document.getElementsByTagName("call");
for(var i=0;i<data.length;++i)
{
var scope = $(data[i]).html();
console.log(scope);
}
});
</script>
<body>
<span class="information">
<call>number 1</call>
<call>number 2</call>
</span>
</body>

nextSibling instead of nextElementSibling?

This isn't exactly a problem in the code, but I cannot understand the reason behind my problem. First, please have a look at the code:
HTML:
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Head First : Javascript</title>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="css.css">
<script type="text/javascript" src="cookie.js"></script>
</head>
<body>
<div id="row1">
<p>False</p>
<p>False</p>
<p>True</p>
<p>True</p>
<p>False</p>
</div>
<div id="row2">
<p>False</p>
<p>False</p>
<p>True</p>
<p>False</p>
<p>False</p>
</div>
<div id="row3">
<p>False</p>
<p>True</p>
<p>True</p>
<p>True</p>
<p>True</p>
</div>
<div id="row4">
<p>True</p>
<p>False</p>
<p>False</p>
<p>True</p>
<p>False</p>
</div>
<script type="text/javascript" src="javascript.js"></script>
</body>
</html>
CSS:
p{
display:inline-block;
width:50px;
margin:30px;
text-align:center;
}
JS:
function setElementColor(){
var numberRows = parseInt(window.prompt("Enter total number of rows that you are seeing on the screen."));
for(var i = 1; i <= numberRows; i++){
var firstElement = document.getElementById('row' + i).firstElementChild;
var counterElement;
//For now, total elements in 1 row = 5
for(var q = 1; q <= 5; q++){
if(q == 1){
firstElement.style.backgroundColor = "red";
counterElement = firstElement.nextSibling;
}
else{
counterElement.style.backgroundColor = "green";
}
counterElement = counterElement.nextElementSibling;
}
}
}
setElementColor();
Now, this might be a stupid question, but it will make sense (I believe). The code that you are seeing is correct, and works without a doubt. But, can you see that nextSibling property in the first if statement? That is what is confusing me.
Now, all paragraphs have spaces between each other, so this means that all browsers will see those spaces as textNode (except IE). Now, by the means of logic, there should have been a nextElementSibling property there, so that the code looks forward for the next Element, ignoring comments/textNodes, but I tried it, and that is not working.
Can someone give me a satisfying reasoning behind that?
In your first if, counterElement is set to the nextSibling, being the textnode
if
{
counterElement = firstElement.nextSibling; //now counterElement is the textnode
}
else
{
}
counterElement = counterElement.nextElementSibling; //no matter if the counterElement is a textnode or a <p> the next element in the sibling tree is a <p>
But regardless of q and the if..else branch taken, immediately after the if..else block, counterElement is set to the next Element sibling, so that regardless if the starting point is the textnode or the containing paragraph, the next element will be the sibling paragraph. The code would behave the same if you would set counterElement = firstElement in the q == 1 block
As an aside, to get rid of the fixed upperbound (columns) and loose the if..else at the same time, you could also use something like
for(var i = 1; i <= numberRows; i++){
var el = document.getElementById('row' + i).firstElementChild;
var q = 1;
while (el!=null){
el.style.backgroundColor = q++ == 1 ? "red" : "green";
el = el.nextElementSibling;
}
}

Updating innerHTML in javascript but erasing past innerHTML

Using Javascript, I want to toggle on and off between 2 images.
So far I am using a counter and then changing my innerHTML based off if the counter is even or odd for when the image is clicked
It works the first time i click the image by replacing the image already there, but after the first time it keeps on adding images instead.
How can i make it change the image after the second time rather than add images when I click?
<!DOCTYPE html>
<html>
<head>
<script>
var x = 0;
function myFunction() {
x++;
var div1 = document.getElementById('div1');
if (x % 2 != 0) {
var y = document.write('<img src="http://www.computric.com/wp-content/uploads/2011/09/119709197585381818TzeenieWheenie_Power_On_Off_Switch_red_2.svg_.med_.ng" alt="sometext" onclick=myFunction()>');
div1.appendChild.innerHtml = y;
} else if (x % 2 == 0) {
var y = document.write('<img src="http://0.tqn.com/d/pcsupport/1/0/Y/A/-/-/on.jpg" alt="some_text" onclick=myFunction()>')
div1.appendChild.innerHTML = y;
}
}
</script>
</head>
<body>
<div id="div1" style="font-size:12px" onclick=myFunction()> <span onclick=myFunction()>
<img src="http://0.tqn.com/d/pcsupport/1/0/Y/A/-/-/on.jpg" alt="some_text">
</span>
</div>
</body>
</html>
If you are only trying to achieve the toggle effect something like this should work:
<!DOCTYPE html>
<html>
<head>
<script>
var x=0;
function myFunction(){
var div1=document.getElementById('div1');
if(x==0){
x=1;
document.getElementById("myimgid").src = "http://www.computric.com/wp-content/uploads/2011/09/119709197585381818TzeenieWheenie_Power_On_Off_Switch_red_2.svg_.med_.ng";
}
else{
x=0;
document.getElementById("myimgid").src = "http://0.tqn.com/d/pcsupport/1/0/Y/A/-/-/on.jpg";
}
}
</script>
</head>
<body>
<div id="div1" style="font-size:12px" onclick=myFunction()>
<span>
<img id="myimgid" src="http://0.tqn.com/d/pcsupport/1/0/Y/A/-/-/on.jpg" alt="some_text">
</span>
</div>
</body>
</html>

Categories