getElementsByClassName doesn't work, but getElementById does? [duplicate] - javascript

This question already has answers here:
getElementsByClassName not working [duplicate]
(2 answers)
Closed 6 years ago.
I've written a script, it's goal is to stop displaying images one and two, while allowing image 3 to remain displayed and move into their place. It works fine when I use div Id's instead of div Classes, but I would prefer to use div classes so I can group the elements like this:
function myFunction() {
var y = document.getElementsByClassName("firstimage secondimage");
if (y.style.display === 'none') {
y.style.display = 'block';
} else {
y.style.display = 'none';
}
}
rather than this (in order to save space should I choose to include more elements):
function myFunction() {
var x = document.getElementById("firstimage");
if (x.style.display === 'none') {
x.style.display = 'block';
} else {
x.style.display = 'none';
}
var y = document.getElementById("secondimage");
if (y.style.display === 'none') {
y.style.display = 'block';
} else {
y.style.display = 'none';
}
}
I thought that just changing the div id's to div classes, and the #imagenumber's to .imagenumber's (in addition to the change in the javascript I described above) would work but the script stops working when I do. I need the script to function in the same way that the code I am pasting below does, but with div classes instead of div Id's. Please tell me where I am going wrong.
CSS:
#firstimage {
width: 100px;
height: 100px;
padding: 0px 0;
text-align: center;
background-color: green;
margin-top:20px;
color: white;
}
#secondimage {
width: 100px;
height: 100px;
padding: 0px 0;
text-align: center;
background-color: blue;
margin-top:20px;
color: white;
}
#thirdimage {
width: 100px;
height: 100px;
padding: 0px 0;
text-align: center;
background-color: red;
margin-top:20px;
color: white;
}
HTML:
<button onclick="myFunction()">Try me</button>
<div id="firstimage">
DIV element.
</div>
<div id="secondimage">
A second DIV element.
</div>
<div id="thirdimage">
A third DIV element.
</div>
Javascript:
function myFunction() {
var x = document.getElementById("firstimage");
if (x.style.display === 'none') {
x.style.display = 'block';
} else {
x.style.display = 'none';
}
var y = document.getElementById("secondimage");
if (y.style.display === 'none') {
y.style.display = 'block';
} else {
y.style.display = 'none';
}
}

document.getElementsByClassName returns an array of elements, so you would need to iterate through that array and operate on each element within that loop.

You should use getElementsByClassName() or querySelectorAll() to collect all div.Klass (Klass being an arbitrary name). The following Snippet uses querySelectorAll() details are commented in source.
SNIPPET
function toggleDiv() {
// Collect all .image into a NodeList
var xs = document.querySelectorAll(".image");
// Declare i and qty for "for" loop
var i, qty = xs.length;
// Use "for" loop to iterate through NodeList
for (i = 0; i < qty; i++) {
// If this div.image at index [i] is "none"...
if (xs[i].style.display === 'none') {
// then make it "block"...
xs[i].style.display = 'block';
} else {
// otherwise set display to "none"
xs[i].style.display = 'none';
}
}
}
#firstimage {
width: 100px;
height: 100px;
padding: 0px 0;
text-align: center;
background-color: green;
margin-top: 20px;
color: white;
}
#secondimage {
width: 100px;
height: 100px;
padding: 0px 0;
text-align: center;
background-color: blue;
margin-top: 20px;
color: white;
}
#thirdimage {
width: 100px;
height: 100px;
padding: 0px 0;
text-align: center;
background-color: red;
margin-top: 20px;
color: white;
}
<button onclick="toggleDiv()">Try me</button>
<div id="firstimage" class='image'>
DIV element.
</div>
<div id="secondimage" class='image'>
A second DIV element.
</div>
<div id="thirdimage" class='img'>
A third DIV element.
</div>
In this function, just using an "array-like" object such as a NodeList demonstrated in the Snippet above. An array would be used in the same manner as it is in the Snippet. Should you want to do more advanced processing of the divs such as running a function on each of them and returned then converting an "array-like" object into an array would be necessary to run methods like map, forEach, slice, etc.

Related

'backgroundColor' not working with javascript

I'm creating a tab menu like this:
function clear_selected() //sets all columns color black
{
var parent = document.querySelector("#container")
var items = document.querySelectorAll(".item")
var n = items.length;
for (var i = 0; i < n; i++)
items[i].style.backgroundColor = "";
}
function plus(itself) //adds another column
{
var parent = itself.parentElement;
var n = parent.childElementCount;
clear_selected();
var n = parent.querySelectorAll(".item").length;
var page = document.createElement("button");
page.className = "item";
page.style.backgroundColor = "blue";
page.textContent = "column"
page.onclick = function() {
clear_selected();
this.style.backgroundColor = "blue";
};
var temp = document.createElement("span");
temp.className = "del"
temp.innerHTML = "×"
temp.onclick = function() { //it's suppose to remove a column and color default as blue
document.querySelector("#main_item").style.backgroundColor = "blue" //THIS LINE ISN'T WORKING
this.parentElement.remove();
};
page.appendChild(temp);
parent.insertBefore(page, parent.childNodes[n]);
}
function see(el) {
clear_selected();
el.style.backgroundColor = "blue";
}
#container {
display: flex;
width: 100%;
height: 50px;
text-align: center;
background-color: yellow;
}
.item {
background-color: black;
color: white;
border: none;
outline: none;
cursor: pointer;
margin: 0.1rem;
padding: 0.1rem;
max-width: 100%;
}
.del {
background-color: red;
display: inline-block;
cursor: pointer;
border-radius: 50%;
width: 0.7rem;
margin-left: 2rem;
}
<div id="container">
<button class="item" id="main_item" style="background-color:blue;" onclick="see(this)">default column </button>
<button class="item" onclick="plus(this)">+</button>
</div>
but when I press the 'x' to remove a column, I want the default column to color blue, but the line of code which is suppose to achieve that isn't working
document.querySelector("#main_item").style.backgroundColor = "blue"
Before pressing 'x':
After pressing 'x' on the last column:
What it SHOULD look like:
I've losing sleep over this, can someone PLEASE tell me why isn't it working?
When you click on the "X", both of your onclick handlers are getting called, including the one that runs clear_selected, which sets the background color to "".
You can fix this by using stopPropagation on the event passed into the onclick function for the "x". That will stop the click event from going up the chain to the parent element of the "x".
temp.onclick = function(e) {
document.querySelector("#main_item").style.backgroundColor = "blue"
this.parentElement.remove();
e.stopPropagation();
};

Display value shoe false in console [duplicate]

This question already has answers here:
why javascript this.style[property] return an empty string? [duplicate]
(2 answers)
Closed 2 years ago.
i have a div and button i click the button fist time no response and click again and show
function banne() {
var ban = document.getElementById("content");
//consloe.log(ban.style.display === "none");
if (ban.style.display === "none") {
ban.style.display = "block";
} else {
ban.style.display = "none";
}
}
.banner-content {
display: none;
height: 100px;
color: #fff;
background: #1b1b1b;
}
<button class="banner" onclick="banne()"> know </button>
<div class="banner-content" id="content">
Some Data
</div>
here the console value show false value but i write the style inline style="display:none" in div class banner-content it working, why the style sheet value not taken ,any idea?
Javascript can't access the style mentioned in the CSS file with the ban.style.display. You have to use getComputedStyle() method.
window.getComputedStyle(ban, null).getPropertyValue("display");
But in your case I think it is better use a class based toggle maybe like,
CSS
.banner-content {
display: none;
height: 100px;
color: #fff;
background: #1b1b1b;
}
.banner-content.active {
display: block;
}
JS
function banne() {
var ban = document.getElementById("content");
ban.classList.toggle("active");
}
While style doesn't register the stylesheet properties, you can check if the style does not equal to "block" and then set it to block, otherwise none. Also see the difference between getComputedStyle and style: https://developer.mozilla.org/en/DOM/window.getComputedStyle
function banne() {
var ban = document.getElementById("content");
//consloe.log(ban.style.display === "none");
if (ban.style.display !== "block") {
ban.style.display = "block";
} else {
ban.style.display = "none";
}
}
.banner-content {
display: none;
height: 100px;
color: #fff;
background: #1b1b1b;
}
<button class="banner" onclick="banne()"> know </button>
<div class="banner-content" id="content">
Some Data
</div>
It's generally not a good idea to use inline event handlers.
Add a listener to the document. To toggle display, use a separate css class (.visible in the snippet) and toggle that. It makes your life so much easier.
document.addEventListener("click", banne);
function banne(evt) {
if (evt.target.classList.contains("banner")) {
document.querySelector("#content").classList.toggle("visible");
}
}
.banner-content {
display: none;
height: 100px;
color: #fff;
background: #1b1b1b;
}
.banner-content.visible {
display: block;
}
<button class="banner"> know </button>
<div class="banner-content" id="content">
Some Data
</div>

hide and show div in javascript

i want to show and then hide div but when i click the button it do not work for the first time, when i click second time it works normally.
i want that it works on first click.
HTML
<p>Click the button</p>
<button onclick="myFunc()">Try it</button>
<div id="divi">
Div region
</div>
CSS
#divi {
width: 50%;
padding: 50px 0;
text-align: center;
background-color: #ccc;
margin-top:20px;
display:none;
}
Javascript
function myFunc() {
var dv = document.getElementById('divi');
if (dv.style.display ==='none') {
dv.style.display = 'block';
} else {
dv.style.display = 'none';
}
}
Here is the pen: https://codepen.io/animaxf/pen/xdVVbK
This is because technically, the style attribute is empty so style.display is actually null. So it first of all makes it display:none; on first click.
If you change the JavaScript to be:
function myFunc() {
var dv = document.getElementById('divi');
if (dv.style.display === 'block') {
dv.style.display = 'block';
} else {
dv.style.display = 'none';
}
}
Basically checking it is block first - it will work.
function myFunc() {
var dv = document.getElementById('divi');
if (dv.style.display === 'block') {
dv.style.display = 'none';
} else {
dv.style.display = 'block';
}
}
#divi {
width: 50%;
padding: 50px 0;
text-align: center;
background-color: #ccc;
margin-top:20px;
display:none;
}
<p>Click the button</p>
<button onclick="myFunc()">Try it</button>
<div id="divi">
Div region
</div>
First click let it fall to the else statement and display it.
After that you are in a good loop.
function myFunc() {
var dv = document.getElementById('divi');
if (dv.style.display == 'block') {
dv.style.display = 'none';
} else {
dv.style.display = 'block';
}
}
#divi {
width: 50%;
padding: 50px 0;
text-align: center;
background-color: #ccc;
margin-top:20px;
display: none;
}
<body>
<p>Click the button</p>
<button onclick="myFunc()">Try it</button>
<div id="divi">
Div region
</div>
</body>
Add this
<div id="divi" style="display:none">
The first time, display is not defined for your div
When you click for the first time there is no style applied (dv.style.display = "") hence, dv.style.display!== 'none' becomes true and dv.style.display = 'none' gets applied.
function myFunc() {
var dv = document.getElementById('divi');
if (dv.style.display !=='none'&& dv.style.display !=="") {
dv.style.display = 'none';
} else {
dv.style.display = 'block';
}
}
#divi {
width: 50%;
padding: 50px 0;
text-align: center;
background-color: #ccc;
margin-top:20px;
display:none;
}
<body>
<p>Click the button</p>
<button onclick="myFunc()">Try it</button>
<div id="divi">
Div region
</div>
</body>
There is no display property set when you click the first time. Just switched the properties – it will work.
https://codepen.io/anon/pen/XRddvd
The first time you click the button, the CSS property display doesn't set yet, therefore when click occurs it checks rather dv.style.display !== 'none' while actually dv.style.display === ''
You can fix this in your code, or you can simply change the CSS as it is more elegant solution. Just apply display: block (or display: none according to your wishful starting state) to #divi inside it's CSS definition.
That is because you change the style of the div, but the display:none attribute is inside the class element. So, the first time the div have not the display attribute and it declare it as none. To fix this, put style="display:none; on the div instead of declaring it inside the css file
When you first load the page, the class is undeclared meaning that you statement if (dv.style.display !=='none') will return true and then apply a display propert dv.style.display = 'none';
Instead, you should use if (dv.style.display =='block') to check whether it is shown.
function myFunc() {
var dv = document.getElementById('divi');
if (dv.style.display =='block') {
dv.style.display = 'none';
} else {
dv.style.display = 'block';
}
}
#divi {
width: 50%;
padding: 50px 0;
text-align: center;
background-color: #ccc;
margin-top:20px;
display:none;
}
<body>
<p>Click the button</p>
<button onclick="myFunc()">Try it</button>
<div id="divi">
Div region
</div>
</body>

How to change class and text of one tag by clicking on another tag?

I don't know how to describe this without making it more complicated.
So look at the result of the code and click on the first link with "Show", then the second one and third one.
When the second link is clicked, first one closes but text remains "Hide" and i want it to change to "Show".
So, when clicking a link, detect if any other link has text "Hide" and change it to "Show".
And please no jQuery...
document.getElementsByClassName("show")[0].onclick = function() {
var x = document.getElementsByClassName("hide")[0];
var y = document.getElementsByClassName("show")[0];
if (x.classList.contains("visible")) {
x.classList.remove("visible");
y.textContent = "Show";
} else {
closeOther();
x.classList.add("visible");
y.textContent = "Hide";
}
};
document.getElementsByClassName("show")[1].onclick = function() {
var x = document.getElementsByClassName("hide")[1];
var y = document.getElementsByClassName("show")[1];
if (x.classList.contains("visible")) {
x.classList.remove("visible");
y.textContent = "Show";
} else {
closeOther();
x.classList.add("visible");
y.textContent = "Hide";
}
};
document.getElementsByClassName("show")[2].onclick = function() {
var x = document.getElementsByClassName("hide")[2];
var y = document.getElementsByClassName("show")[2];
if (x.classList.contains("visible")) {
x.classList.remove("visible");
y.textContent = "Show";
} else {
closeOther();
x.classList.add("visible");
y.textContent = "Hide";
}
};
function closeOther() {
var visible = document.querySelectorAll(".visible"),
i, l = visible.length;
for (i = 0; i < l; ++i) {
visible[i].classList.remove("visible");
}
}
.style {
background-color: yellow;
width: 200px;
height: 200px;
display: inline-block;
}
.hide {
background-color: red;
width: 50px;
height: 50px;
display: none;
position: relative;
top: 50px;
left: 50px;
}
.hide.visible {
display: block;
}
<div class="style">
Show
<div class="hide">
</div>
</div>
<div class="style">
Show
<div class="hide">
</div>
</div>
<div class="style">
Show
<div class="hide">
</div>
</div>
I tried to write a solution which didn't use any javascript at all and worked using CSS alone. I couldn't get it to work though - CSS can identify focus but it can't identify blur (ie. when focus has just been removed).
So here is a solution which uses javascript and the classList API, instead:
var divs = document.getElementsByTagName('div');
function toggleFocus() {
for (var i = 0; i < divs.length; i++) {
if (divs[i] === this) continue;
divs[i].classList.add('show');
divs[i].classList.remove('hide');
}
this.classList.toggle('show');
this.classList.toggle('hide');
}
for (let i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', toggleFocus, false);
}
div {
display: inline-block;
position: relative;
width: 140px;
height: 140px;
background-color: rgb(255,255,0);
}
.show::before {
content: 'show';
}
.hide::before {
content: 'hide';
}
div::before {
color: rgb(0,0,255);
text-decoration: underline;
cursor: pointer;
}
.hide::after {
content: '';
position: absolute;
top: 40px;
left: 40px;
width: 50px;
height: 50px;
background-color: rgb(255,0,0);
}
<div class="show"></div>
<div class="show"></div>
<div class="show"></div>
Like this?
Just added following to closeOther():
visible = document.querySelectorAll(".show"),
i, l = visible.length;
for (i = 0; i < l; ++i) {
visible[i].textContent="Show";
}

How to animate the list?

This is my JSFiddle
As you can see from the fiddle that there is a list that is being scrolled with the help of arrows.. So what I want is to animate that transition when the list visible and hidden.
I don't know about the animation. I have seen many examples and tried to adjust them with my example but it's not working... How do I get the list to animate?
$(document).ready(function(){
var code='';
for(var i=1;i<=20;i++)
{
code+="<li>list Item "+i+"</li>";
}
$('#list-items').html(code);
});
var list_items = [];
var index = 0;
var list_length = 0;
function getAllListItems() {
var temp = document.getElementsByTagName('li');
for (i = 0; i < temp.length; i++) {
list_items.push(temp[i]);
}
list_length = temp.length;
}
getAllListItems();
function move(dir) {
if (dir == left) {
list_items[index].style.display = 'block';
index--;
if (index < 0) {
index = 0;
}
} else if (dir == right) {
list_items[index].style.display = 'none';
if (index >= ((list_length) - 1)) {
index = (list_length) - 1;
} else {
index++;
}
} else {}
}
* {
box-sizing: border-box;
}
ul {
float:left;
height:50px;
width: 600px;
overflow: hidden;
}
ul li {
text-align: center;
border: 2px solid black;
width: 100px;
height: 50px;
float: left;
list-style-type: none;
background-color: aquamarine;
}
ul li:first-child {
display: block;
}
#left, #right {
float:left;
height:50px;
background-color:aqua;
font-size:2em;
padding-left: 20px;
padding-right:20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body onload='getAllListItems()'>
<div id='t'></div>
<button id='left' onClick="move(left)">
<</button>
<ul id='list-items'>
</ul>
<button id='right' onClick='move(right)'>></button>
</body>
You can easily just replace your lines:
list_items[index].style.display = 'block';
list_items[index].style.display = 'none';
with the jQuery show() and hide() functions:
$(list_items[index]).show("slow");
$(list_items[index]).hide("slow");
As demonstrated in my updated version of your Fiddle
For different transitions, you can use the animate() function, which lets you tell it what css properties to affect. In addition to numeric values, jQuery also supports the special values 'show', 'hide', and 'toggle' (which, incidentally, will show, hide, or toggle the show/hide status of an element using that property). So for instance, if you wanted to shrink them only horizontally and leave the vertical alone, you could change the .show() and .hide() calls to:
$(list_items[index]).animate({width:'show'}, 600);
$(list_items[index]).animate({width:'hide'}, 600);
I've demonstrated this in another updated Fiddle

Categories

Resources