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>
Related
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.
I need help with homework. I need to create a Wayfinder by highlighting an active menu item in a dynamically generated navigation. My code does not respond when a menu item is changed on a button click. Here are my rendered HTML and JavaScript codes.
var urlLink = "http://localhost/acme/products/?action=category&categoryName=Rocket";
var path = urlLink.split("=").pop();
console.log(path);
liContainer = document.getElementById("navMenu");
const navAnchor = liContainer.getElementsByClassName('mainMenu');
/*
navAnchor.forEach(anchor => {
anchor.addEventListener('click', addActive);
});
*/
for (var i = 0; i < navAnchor.length; i++) {
navAnchor[i].addEventListener("click", addActive);
}
function addActive(e) {
var liAnchor = liContainer.target.tagName("a").getAttribute("href");
if (liAnchor.split("=").pop() === path) {
const current = document.querySelector('li.active');
current.className = current.className.replace(" active", "");
e.target.className += " active";
}
}
.active {
background-color: red;
color: white;
padding: 10px
}
<ul id="navMenu">
<li class="mainMenu active">Home</li>
<li class="mainMenu">Cannon</li>
<li class="mainMenu">Explosive</li>
<li class="mainMenu">Misc</li>
<li class="mainMenu">Rocket</li>
<li class="mainMenu">Trap</li>
</ul>
I want the active menu to be highlighted.
I resolved my own issue using the following code:
var path = window.location.href.split("=").pop();
var liContainer = document.getElementById("navMenu");
const navAnchor = liContainer.getElementsByClassName('mainMenu');
for (var i = 0; i < navAnchor.length; i++) {
var liAnchor = navAnchor[i].getElementsByTagName("a");
for (var j = 0; j < liAnchor.length; j++) {
linkPath = liAnchor[j].getAttribute("href").split("=").pop();
if (linkPath === path) {
var current = document.getElementsByClassName("active");
current[0].className = current[0].className.replace(" active", "");
navAnchor[i].className += " active";
}
}
}
Im trying to improve my as I call it "contenthandler". What it does is that it changes different articles when I click different buttons. Im happy on how it works, but I feel this is not the best practise and I want some advices on how to maybe shorten it even more or use any other way to do this.
Im not intrested in any jQuery or other libaries at the moment.
document.addEventListener("click", function(e){
var article = document.getElementsByClassName("test"); // Article becomes an array.
var buttonClick = e.target.className;
switch (buttonClick){
case "one":
test(article);
article[0].style.display = "";
break;
case "two":
test(article);
article[1].style.display = "";
break;
case "three":
test(article);
article[2].style.display = "";
break;
}
function test(article){
for (var i = 0; i < article.length; i++){
article[i].style.display = "none";
}
}
});
//html
<ul>
<li class="buttonNav"><h2 class="one">Show 1</h2></li>
<li class="buttonNav"><h2 class="two">Show 2</h2></li>
<li class="buttonNav"><h2 class="three">Show 3</h2></li>
</ul>
<article class="test" style="display: none">1</article>
<article class="test" style="display: none">2</article>
<article class="test" style="display: none">3</article>
[Edit]
I remade the script from the answer I got, but I made a small change to it and made it dynamic so I do not need to hard code the "menu" in the script file.
var getClassName = document.querySelectorAll("h2");
var classNamesArray = [];
for (var i = 0; i < getClassName.length; i++){
classNamesArray.push(getClassName[i].className.toString());
};
document.addEventListener("click", function (e) {
var article = document.getElementsByClassName("test"); // Article becomes an array.
var buttonClick = e.target.className,
// Maintain list of class names in an order
validClassNames = classNamesArray,
index = -1;
for (var i = 0; i < validClassNames.length; i++) {
if (buttonClick === validClassNames[i]) {
index = i;
break;
}
}
if (index >= 0) {
test(article);
article[index].style.display = "";
}
});
function test(article) {
for (var i = 0; i < article.length; i++) {
article[i].style.display = "none";
}
}
One approach I can think of is
document.addEventListener("click", function (e) {
var article = document.getElementsByClassName("test"); // Article becomes an array.
var buttonClick = e.target.className,
// Maintain list of class names in an order
validClassNames = ["one", "two", "three"],
index = -1;
for (var i = 0; i < validClassNames.length; i++) {
if (buttonClick === validClassNames[i]) {
index = i;
break;
}
}
if (index >= 0) {
test(article);
article[index].style.display = "";
}
});
function test(article) {
for (var i = 0; i < article.length; i++) {
article[i].style.display = "none";
}
}
Also move the function definition to outside of the event handler.
Fiddle
Hi I was wondering if anyone could help me out. I need to apply an array I created in Java Script on the HTML page that already has the order list created.I keep on getting error messages that say "Cannot read property of 'inner.HTML' undefined.
Any help would be greatly appreciated:)
thanks!
Here is my code:
< div id = "results" >
< ul >
< li id = "1-1" > < /li>
<li id="1-2"></li >
< li id = "1-3" > < /li>
<li id="1-4"></li >
< li id = "1-5" > < /li>
</ul >
< /div>
</article >
< script >
//declared global variable with an array of variables.
var places = ["Switzerland", "Canada", "Australia", "Norway", "New Zealand"]
// function to place the country's name in the
// li id.
function processPlaces() {
var locations = "";
for (var i = 0; i < places.length; i++) {
var listItem = i + 1;
var list = document.getElementById("1-" + listItem);
locations = list.getElementsByTagName("li");
locations[1].innerHTML += places[i];
}
}
//runs setUpPage () function when page loads.
if (window.addEventListener) {
window.addEventListener("load", processPlaces, false);
} else if (window.attachEvent) {
window.attachEvent("onload", processPlaces, false);
} < /script>
ids cannot start with a number, so preface them with l or some letter (you can see the change in the snippet).
HTML elements cannot have spaces immediately following <, so < div> will render as text, and < /div> will also render as text. Make sure to remove all the excessive spacing.
Further, when you access the element with getElementById that is the actual <li> element, and using getElementsByTagName inside of that element will find nothing because there are no children to the <li> elements. Instead of taking that approach, remove it and simply use the <li> element you already have from using getElementById. Once you make these changes, your code should run as intended.
//declared global variable with an array of variables.
var places = ["Switzerland", "Canada", "Australia", "Norway", "New Zealand"]
// function to place the country's name in the
// li id.
function processPlaces() {
var locations = "";
for (var i = 0; i < places.length; i++) {
var listItem = i + 1;
var list = document.getElementById("l1-" + listItem);
list.innerHTML = places[i];//directly access <li> element
//locations = list.getElementsByTagName("li");
//locations[1].innerHTML += places[i];
}
}
//runs setUpPage () function when page loads.
if (window.addEventListener) {
window.addEventListener("load", processPlaces, false);
} else if (window.attachEvent) {
window.attachEvent("onload", processPlaces, false);
}
<div id = "results">
<ul>
<li id = "l1-1"></li>
<li id = "l1-2"></li >
<li id = "l1-3"></li>
<li id = "l1-4"></li >
<li id = "l1-5"></li>
</ul >
</div>
If the array is ordered already, why not just append to the <ul>? First set and id on your unordered list <ul id="myList">
for (var i = places.length - 1; i >= 0; i--) {
$('#myList').after($('<li />', { 'text': places[i] }));
};
JSFiddle
Cleaned it up a bit.
You can't have spaces right after < in your html tags.
Also, you cant start IDs with numbers.
Edit: Too slow, Travis answer explains this much better :)
var places = ["Switzerland", "Canada", "Australia", "Norway", "New Zealand"];
function processPlaces() {
for (var i = 0; i < places.length; i++) {
document.getElementById('a-' + (i+1)).innerHTML = places[i];
}
}
if (window.addEventListener) {
window.addEventListener("load", processPlaces, false);
} else if (window.attachEvent) {
window.attachEvent("onload", processPlaces, false);
}
<div id="results">
<ul>
<li id="a-1"></li>
<li id="a-2"></li>
<li id="a-3"></li>
<li id="a-4"></li>
<li id="a-5"></li>
</ul>
</div>
I have a list when click on the button of each record in the list I delete it.
I use this HTML5 on Anroaid by PhoneGap wrapper, on a computer the Record is deleted, on Android not! What could be the reason?
Here my code:
My list:
<ul id="MyList" data-role="listview" data-divider-theme="b" data-inset="true">
</ul>
I fill the list with this function:
function FillBookMarkListByStation() {
var ul = $("#MyList");
for (var i = 0; i < Local.length; i++) {
var newLI = document.createElement("LI");
ul.appendChild(newLI);
newLI.innerHTML = '<a href="xxx.html" onclick="x();" > <p>...</p>' +
'<a id="btnClear' + i + '" data-role="button" data-icon="delete" data-theme="b"></a>
</a>';
$("#btnClear" + i).click(function () { Clear(ul, newLI); });
}
$('ul').listview('refresh');
}
Function clear:
function Clear(List, Delete) {
//Remove from the list
List.removeChild(Delete);
//Remove from the local storage
for (var i = 0; i < Local.length; i++) {
//Checking is variable for check the data in the item
if (Local[i].Checking == Delete.dataset.checking) {
if (Local.length == 1)
Local= [];
else {
for (var j = i; j < Local.length - 1; j++) {
Local[i] = Local[i] + 1;
}
Local.length--;
}
Local["loc"] = JSON.stringify(Local);
}
}
}
On computer works fine,
on Android is delete from the screen but not from loacl storage,
on presentation of the list is still showing the deleted item.
Problem solved, android will not know the dataset and therefore is stuck ..