how could get children nodes by getElementsByClassName - javascript

I am trying to access to children of body by getElementById using following code:
function myFunction() {
var body = document.getElementById("textBody");
var x = body.getElementsByClassName("myDIV");
for(var i=0; i < x.length; i++) {
var y = x[i].getElementsByTagName("h1");
var z = x[i].getElementsByTagName("mynode");
for (var i = 0; i < y.length; i++) {
y[i].setAttribute("class", "democlass");
z[i].setAttribute("class", "democlass");
}
}
}
.democlass {
color: red;
}
<body id="textBody">
<div class="myDIV">
<h1 name="demoNode">Hello World</h1>
<mynode> hi there </mynode>
</div>
<div class="myDIV">
<h1 name="demoNode">Hello World</h1>
<mynode> hi there </mynode>
</div>
<h1 name="demoNode">Hello World</h1>
<p>Click the button to create a "class" attribute with the value "democlass" and insert it to the H1 element above.</p>
<button onclick="myFunction()">Try it</button>
</body>
The code should color the header text into red color. But it seems not to be working for me. Would you please let me know why? What I know it could not have access to the exact nodes which I am waiting for.

In your styling you are referring to the democlass as a class whereas it is set as an id attribute. You can refer to my code for changes
<!DOCTYPE html>
<html>
<head>
<title>Hello</title>
</head>
<body class="textBody">
<div class="myDIV">
<h1 name="demoNode">Hello World</h1>
<mynode> hi there </mynode>
</div>
<div class="myDIV">
<h1 name="demoNode">Hello World</h1>
<mynode> hi there </mynode>
</div>
<h1 name="demoNode">Hello World</h1>
<p>Click the button to create a "class" attribute with the value "democlass" and insert it to the H1 element above.</p>
<button onclick="myFunction()">Try it</button>
</body>
<script>
function myFunction() {
//var body = document.getElementsByClassName("textBody"); (This code is not required)
var x = document.getElementsByClassName("myDIV");
for(var i=0; i < x.length; i++) {
var y = x[i].getElementsByTagName("h1");
var z = x[i].getElementsByTagName("mynode");
//initialise the second loop with a different variable
for (var j = 0; j < y.length; j++) {
y[j].setAttribute("id", "democlass");
z[j].setAttribute("id", "democlass");
}
}
}
</script>
<style type="text/css">
//Id reference for styling
#democlass {
color: red;
}
</style>
</html>

Related

display different comand and result from getElementsByClassName() Method

i just wanna ask how to change or display the different color with "getElementsByClassName() Method" in javascript,so here i want to change the bacground color blue from class "ex",and color red form class "example",but it doesnt work.
<!DOCTYPE html>
<html>
<head>
<style>
.example {
border: 1px solid black;
padding 8px;
}
</style>
</head>
<body>
<h1>The Document Object</h1>
<h2>The getElementsByClassName() Method</h2>
<p>Change the background color of all elements with class="example":</p>
<div class="example">
A div with class="example"
</div>
<br>
<div class="ex">
A div with class="example"
</div>
<p class="example">
A p element with class="example".
</p>
<p class="ex">
A p element with class="example".
</p>
<p>A <span class="example">span</span> element with class="example".</p>
<script>
const collection = document.getElementsByClassName("example");
for (let i = 0; i < collection.length; i++) {
collection[i].style.backgroundColor = "red";
}
const collection = document.getElementsByClassName("ex");
for (let i = 0; i < collection.length; i++) {
collection[i].style.backgroundColor = "blue";
}
</script>
</body>
</html>
your code works fine but you had two variables with the name collection rename one of them
<!DOCTYPE html>
<html>
<head>
<style>
.example {
border: 1px solid black;
padding 8px;
}
</style>
</head>
<body>
<h1>The Document Object</h1>
<h2>The getElementsByClassName() Method</h2>
<p>Change the background color of all elements with class="example":</p>
<div class="example">
A div with class="example"
</div>
<br>
<div class="ex">
A div with class="example"
</div>
<p class="example">
A p element with class="example".
</p>
<p class="ex">
A p element with class="example".
</p>
<p>A <span class="example">span</span> element with class="example".</p>
<script>
const collection = document.getElementsByClassName("example");
for (let i = 0; i < collection.length; i++) {
collection[i].style.backgroundColor = "red";
}
const collection2 = document.getElementsByClassName("ex");
for (let i = 0; i < collection2.length; i++) {
collection2[i].style.backgroundColor = "blue";
}
</script>
</body>
</html>
What does "doesn't work" mean? Is ex blue, and example uncolored? Are none colored?
Try checking the output in console (Developer tools - F12). I am certain you will receive an error using your snippet, as you redefine the collection variable twice. Use let instead of const if you plan on using a solution which changes a variable's value after assignment. Alternatively, define another variable for your second for-loop.
Here's your snippet corrected if you're still not sure:
let collection = document.getElementsByClassName("example");
for (let i = 0; i < collection.length; i++) {
collection[i].style.backgroundColor = "red";
}
collection = document.getElementsByClassName("ex");
for (let i = 0; i < collection.length; i++) {
collection[i].style.backgroundColor = "blue";
}

I want to have multiple sliders on the same page

This is what i tried to do i want the program to get the product number and then choose the right article to show, the first one works fine but the second one doesn't i think i need another implementation rather than using the parent element.
var ids = ["view_0", "view_1", "view_2", "view_3"]
let current_id = 0;
function next(product) {
var parent =document.getElementById(ids[current_id]).parentElement.id;
if(product==parent){
let last_array_position = ids.length;
document.getElementById(ids[current_id]).classList.remove("show");
current_id++;
if (current_id >= last_array_position) {
current_id = 0;
}
document.getElementById(ids[current_id]).classList.add("show");
}
}
<style>
#1 img {
display: none;
}
#1 img.show {
display: block;
}
</style>
<!DOCTYPE html>
<html>
<head>
<title>Multiple Slider</title>
</head>
<body>
<article id="1">
<img class="show" id="view_0"></img>
<img id="view_1"></img>
<img id="view_2"></img>
<img id="view_3"></img>
<button><</button>
<button onclick="next(1)">></button>
</article>
<article id="2">
<img class="show" id="view_0"></img>
<img id="view_1"></img>
<img id="view_2"></img>
<img id="view_3"></img>
<button><</button>
<button onclick="next(2)">></button>
</article>
</body>
Getting error:
Uncaught TypeError: Cannot read properties of null (reading 'classList')
var ids = ["view_0", "view_1", "view_2", "view_3"]
let current_id = 0;
function next() {
let last_array_position = ids.lastIndexOf;
document.getElementById(ids[current_id]).classList.remove("show");
current_id = current_id + 1;
document.getElementById(ids[current_id]).classList.add("show");
if (current_id < last_array_position) {
current_id = 0;
}
}
<!DOCTYPE html>
<html>
<head>
<title>Multiple Slider</title>
</head>
<body>
<div id="product1">
<p class="show" id="view_0">1</p>
<p id="view_1">2</p>
<p id="view_2">3</p>
<p id="view_3">4</p>
<button><</button>
<button onclick="next()">></button>
</div>
</body>
The length of an array is in the length property, not lastIndexOf (that's a method that you use to search for the last occurrence of a value).
You need to check if the index exceeds that before you try to use the element.
Your if statement also has the wrong condition, it should be >=, not <.
var ids = ["view_0", "view_1", "view_2", "view_3"]
let current_id = 0;
function next() {
let last_array_position = ids.length;
document.getElementById(ids[current_id]).classList.remove("show");
current_id++;
if (current_id >= last_array_position) {
current_id = 0;
}
document.getElementById(ids[current_id]).classList.add("show");
}
#product1 p {
display: none;
}
#product1 p.show {
display: block;
}
<!DOCTYPE html>
<html>
<head>
<title>Multiple Slider</title>
</head>
<body>
<div id="product1">
<p class="show" id="view_0">1</p>
<p id="view_1">2</p>
<p id="view_2">3</p>
<p id="view_3">4</p>
<button><</button>
<button onclick="next()">></button>
</div>
</body>
You are trying to access the element which is going out of bounds because the condition check is happening later. You need to check the condition before accessing the classList and adding show to it. Also, you can keep last_array_position = ids.length outside your function as that is not gonna change.
Here's a more simpler solution for more than one slider section in a page:
function next(productId) {
var tags = document.getElementById(productId).getElementsByTagName("p");
var index;
for (let i = 0; i < tags.length; i++) {
if (tags[i].className == "show") {
index = i;
break;
}
}
tags[index].classList.remove("show")
index = (index + 1) == tags.length ? 0 : index + 1;
tags[index].classList.add("show")
}
p {
display: none;
}
p.show {
display: block;
}
<!DOCTYPE html>
<html>
<head>
<title>Multiple Slider</title>
</head>
<body>
<div id="product1">
<p class="show" id="view_1_0">1</p>
<p id="view_1_1">2</p>
<p id="view_1_2">3</p>
<p id="view_1_3">4</p>
<button><</button>
<button onclick="next('product1')">></button>
</div>
<div id="product2">
<p class="show" id="view_2_0">1</p>
<p id="view_2_1">2</p>
<p id="view_2_2">3</p>
<p id="view_2_3">4</p>
<button><</button>
<button onclick="next('product2')">></button>
</div>
</body>

How to make h1 color change when click on it's container?

Whenever I click on a container which is also the h1. But I want to do when I click on the container. I want to make its h1 color blue. Im stuck on the part making the h1 blue.
var container = document.getElementsByClassName('container');
var h1 = document.getElementsByTagName('h1');
// Put event listener on each container
for(var i = 0; i < container.length; i++) {
container[i].addEventListener('click', function() {
// This isn't working
h1[i].style.color = 'blue';
})
}
<div class="container">
<h1>HELLO</H1>
</div>
<div class="container">
<h1>HELLO</H1>
</div>
<div class="container">
<h1>HELLO</H1>
</div>
<div class="container">
<h1>HELLO</H1>
</div>
You are referring to the wrong element when you used h1[i].style...
Use this instead and it will work fine. See code below:
var container = document.getElementsByClassName('container');
var h1 = document.getElementsByTagName('h1');
// Put event listener on each container
for(var i = 0; i < container.length; i++) {
container[i].addEventListener('click', function() {
// Get the 1st H1 inside current container
this.getElementsByTagName('h1')[0].style.color = 'blue';
})
}
<div class="container">
<h1>HELLO</H1>
</div>
<div class="container">
<h1>HELLO</H1>
</div>
<div class="container">
<h1>HELLO</H1>
</div>
<div class="container">
<h1>HELLO</H1>
</div>
var container = document.getElementsByClassName('container');
var h1 = document.getElementsByTagName('h1');
// Put event listener on each container
for(var i = 0; i < container.length; i++) {
container[i].addEventListener('click', function() {
this.firstElementChild.style.color="blue"
})
}
Inside the container[i].addEventListener('click', ....) this is the HTML Element of the container. Therefore, calling this.firstElementChild will grab the H1 of that container and change it's color to blue. If you add anything before the H1, just call the children function on this and grab the h1 element.
Neither of the answers that have been posted directly address the issue. They rely on changing the entire color of the .container element, or on the <h1> always being the immediate first child of .container.
The problem that you have is that you have is that your i variable is out of scope, and cannot be used inside the event handler you're defining. We can get around this by wrapping the handler function in a closure as follows:
var container = document.getElementsByClassName('container'),
h1 = document.getElementsByTagName('h1');
for(var i = 0; i < container.length; i++)
{
container[i].onclick = (function(i) {return function() {
h1[i].style.color = 'blue';
};})(i);
};
<div class="container">
<h1>HELLO</H1>
</div>
<div class="container">
<h1>HELLO</H1>
</div>
<div class="container">
<h1>HELLO</H1>
</div>
<div class="container">
<h1>HELLO</H1>
</div>
Notice that the above will only change the colour of the <h1>. Of course, this assumes that all of your <h1> elements are always matched in number and index by the .container elements (but I assume that they are, from your question).

How to create pair game using node values and set a setTimeout() method

I want to create a pair game that if the same textnode is matched it will set the background in white to reveal the matched textnode if not it will set a timeout and get back in original state.
The Problem of this is if I use the childNodes.nodeValue in match it saids that ChildNodes.nodeValue is not a function. And I try another code. I declare a variable that calls the element tag name of div which is I append a textNode in div. I want to compare two consecutive childNodes of div and if it is the same node, I change the color of the background to white. and I use the setTimout method, if not the color of background will go back again in original state which is black, I am pretty confused about this.
can you scan my code and help me to figure out what is the problem of this code?
here is the code.
<html>
<head>
<style>
div.row {
clear : left;
margin: auto;
width: 520px;
}
div.col {width:100px;
height:100px;
border: 3px solid black;
float : left;
margin: 10px;
font-size: 75px;
text-align: center;
background-color: black;
}
</style>
</head>
<body>
<div class="row">
<div id="00" class="col"></div>
<div id="01"class="col"></div>
<div id="02"class="col"></div>
<div id="03"class="col"></div>
</div>
<div class="row">
<div id="10" class="col"></div>
<div id="11"class="col"></div>
<div id="12"class="col"></div>
<div id="13"class="col"></div>
</div>
<div class="row">
<div id="20" class="col"></div>
<div id="21"class="col"></div>
<div id="22"class="col"></div>
<div id="23"class="col"></div>
</div>
<div class="row">
<div id="30" class="col"></div>
<div id="31"class="col"></div>
<div id="32"class="col"></div>
<div id="33"class="col"></div>
</div>
<script>
var size = 4;
var player = 0;
var board = new Array(size);
for (var i = 0; i < size; i++) {
board[i] = new Array(size);
for (var j = 0; j < size; j++) {
board[i][j] = 0;
}
}
var div_elements = document.getElementsByClassName("col");
for (var i = 0; i < div_elements.length;i++) {
div_elements[i].addEventListener("click", function() {mclick(this);});
}
var count=0;
function mclick(obj) {
if(match(div_elements.childNodes[0].nodeValue) == match(div_elements.childNodes[1].nodeValue)
{
obj.style.backgroundColor="white";
}
else{
setTimeout(function(){ obj.style.backgroundColor="white" }, 1000);
}
}
function shuffle() {
var value;
var text;
var text_node;
for (var i = 0; i < (size * size) ; i++) {
value = Math.ceil(Math.random() * 8);
board[Math.floor(i/4)][i %4] = value;
}
for (var i = 0; i < div_elements.length; i++)
{
text = board[Math.floor(i/4)][i%4];
text_node = document.createTextNode( text);
div_elements[i].appendChild(text_node);
}
}
shuffle();
</script>
</body>
</html>
You must be more specific. What kind of problem are you having? What are the error messages? What do you do that triggers the problem?
At least, put the code in a pastebin.com or something similar so that others don't need to setup a project for testing your whole stuff.

Easiest way to display childNodes NodeList? (Beginner)

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.

Categories