Identifier 'i' has already been declared problem - javascript

I try to do a accordion for display content and i get this problem on mi js code, I'm sure it's an easy problem to fix, but I can't see it right now, I need help to see it.
JS code:
var acc = document.getElementsByClassName("servicon-button");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.maxHeight) {
panel.style.maxHeight = null;
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
}
});
}
My html of this:
<button class="servicon-button"> <img src="icons/computer.svg" alt=""> </button>
<div class="panel">

try declaring the i variable inside the for loop, putting the variable inside the for loop ensures that the variable is only used inside the loop which is a good thing, if you put it outside, it will mix with other variables in the code in the global scopes which can cause problems like reassigning or redeclaring variables
const acc = document.getElementsByClassName("servicon-button");
for (let i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
const panel = this.nextElementSibling;
if (panel.style.maxHeight) {
panel.style.maxHeight = null;
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
}
});
}
sidenote : var is not really recommended, use const and let instead

Instead of declaring var i before the loop, declare it inside the for loop like this:
for (let i = 0; i < acc.length; i++) { ... This is where the error is coming from.

Related

I try to make several divs show individually on click

I have 6 divs, and each div when click will show a pop up window, now, the problem is that it is not working. Here is my code, I don't know what i am doing wrong:
var clickMe = document.getElementsByClassName("skill-items__item");
for (i = 0; i < clickMe.length; i++) {
clickMe[i].addEventListener("click", function() {
var ShowMe = this.nextElementSibling;
for (i = 0; i < ShowMe.length; i++) {
if (ShowMe[i].style.display === "block") {
ShowMe[i].style.display = "none";
} else {
ShowMe.style.display = "block";
}
}
});
}
Your problem is that you're using i twice. Your second for loop is overwriting the i variable from the first for loop.
Don't worry, we've all been there. Good luck!

My javascript function works just within the html file, but if a move it to is own file doesnt work why?

In my project, I am also using bootstrap 3, HTML, CSS.
I have correctly linked the HTML document to the javaScript file.
this is the code:
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.display === "block") {
content.style.display = "none";
} else {
content.style.display = "block";
}
});
}

Can't get the correct number of buttons with specific class name

I want to count the number of buttons inside a div, I add the buttons dynamically from a js file. When I run the program on the browser, the buttons appear correctly and when I inspect the code from the browser all the elements and class names are correct. However, when I try to log the number of buttons with a class name of "accordion" it returns 0 when it should return 4.
Here's the HTML code:
<body class="d-flex justify-content-center" style="width: 100%;height: 50%;">
<div class="container" style="width: 500px;"><img src="assets/img/header_image.png" style="width: 100%;">
<div class="row" style="margin-top: 20px;">
<div id="accordion-div" class="col">
</div>
</div>
</div>
<script src="assets/js/jquery.min.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="index.js"></script>
The javascript code:
var acc = document.getElementsByClassName("accordion");
var acc_div = document.getElementById("accordion-div")
var i;
add_accordion_item = (name, details) => {
var btn = document.createElement('button');
acc_div.appendChild(btn);
btn.innerHTML = name;
btn.className += "btn btn-success accordion";
btn.type = "button"
var details = document.createElement('div');
acc_div.appendChild(details);
details.innerHTML = details
details.className += "panel"
}
url = '.....'
make_list = () => {
$.getJSON(url, function(data){
for(var i = 0; i<data["number_of_threats"]; i++){
name = data["info"][i]["name"];
details = "details"
add_accordion_item(name, details);
}
});
}
make_list()
console.log(document.getElementsByClassName("accordion").length)
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
});
}
This should show a button that when pressed it should show the div with the details. But the for never runs as the acc.length is 0.
Thanks for you time
I think that a node array don't get length attribut.
You should use forEach instead of for loop like
acc.forEach(function(element) {
element.addEventListener("click", function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
});
})
I hope it helps you
I think you have missed to add a class accordion as to any element. because I cant see any element with a class name as accordion in your html code.
But inside to your javascriptcode, on first line you are trying to search an element with a class name as accordion.
The variable acc doesn't auto update after you declared it in the beginning.
You will need to retrieve the value of acc variable again just above the for loop.
i.e. just above the for loop you need to add the line like this
acc = document.getElementsByClassName("accordion");
for (i = 0; i < acc.length; i++) {
....
I fixed it by adding the listener inside the make_list function
var acc = document.getElementsByClassName("accordion");
var acc_div = document.getElementById("accordion-div")
var i;
add_accordion_item = (name, details) => {
var btn = document.createElement('button');
acc_div.appendChild(btn);
btn.innerHTML = name;
btn.className += "btn btn-success accordion";
btn.type = "button"
var details = document.createElement('div');
acc_div.appendChild(details);
details.innerHTML = details;
details.className += "panel";
add_listener(btn);
}
url = '.....'
make_list = () => {
$.getJSON(url, function(data){
for(var i = 0; i<data["number_of_threats"]; i++){
name = data["info"][i]["name"];
details = "details"
add_accordion_item(name, details);
}
});
}
make_list()
function add_listener(element) {
element.addEventListener("click", function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
});
}

JS collapse isn't displaying my content correctly

I've been trying to get this to work but sadly I lack the knowledge in JS.
The content gets behind the collapsible div most of the time
is anyone able to help me fix this?
This is my js file :
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.maxHeight){
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + 50 + "px";
}
});
}
https://codepen.io/FGamerNL/pen/qYJOxx
I think you need set maxHeight for parentElement has "content" class when click to children.
The max-height of your outer <div class="content"></div> is not recalculated, when you toggle one of it’s children.

Assign max-height to inner element after toggle

many thanks to anyone who can help me solving the issue
Here is HTML and JS:
var acc = document.getElementsByClassName("razvernut");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function(){
this.classList.toggle("razvorot");
var panel = document.getElementsByClassName('sub-menu');
if (panel.style.maxHeight){
panel.style.maxHeight = null;
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
}
}
}
<li class="razvernut">
<span class="span"></span>
<span class="otherspan"></span>
<a>Show ul.sub-menu with 0 max-height</a>
<ul class="sub-menu">...</ul>
</li>
My skill in js is quite low, please tell me where is the mistake as script cant define the .sub-menu within the page :\
getElementsByClassName returns a list of elements, you can either iterate over the list and use each element inside the loop, or in your case you can use panel[0].
var acc = document.getElementsByClassName("razvernut");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function(){
this.classList.toggle("razvorot");
var panel = document.getElementsByClassName('sub-menu');
if (panel[0].style.maxHeight){
panel[0].style.maxHeight = null;
} else {
panel[0].style.maxHeight = panel[0].scrollHeight + "px";
}
}
}
<li class="razvernut">
<span class="span"></span>
<span class="otherspan"></span>
<a>Show ul.sub-menu with 0 max-height</a>
<ul class="sub-menu">...</ul>
</li>

Categories