This question already has answers here:
Why can't I call a function named clear from an onclick attribute?
(3 answers)
Closed 1 year ago.
The 'X' is unable to display "none" to the UL element. Is there a problem with the getElement? or should I use query selector.
function clear() {
var hide = document.getElementById("myUL1");
hide.style.display = "none";
}
span {
cursor: pointer;
}
<div>
<ul id="myUL1">
<li>list</li>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
<div>Clear list <span onclick="clear()">X</span></div>
</div>
Rename the function. - there is already a clear function that interferes with yours
function clearIt() {
var hide = document.getElementById("myUL1");
hide.style.display = "none";
}
span {
cursor: pointer;
}
<div>
<ul id="myUL1">
<li>list</li>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
<div>Clear list <span onclick="clearIt()">X</span></div>
</div>
Better alternative is to not have inline event handlers
document.getElementById("container").addEventListener("click",function(e) {
const tgt = e.target;
if (tgt.classList.contains("clear")) {
tgt.closest("div").querySelector("ul").classList.add("hide")
}
})
span {
cursor: pointer;
}
.hide { display:none; }
<div id="container">
<ul id="myUL1">
<li>list</li>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
Clear list <span class="clear">X</span>
</div></div>
Try this - it is better to use JavaScript eventlisteners when possible:
const targetSpan = document.getElementById("mySpan");
const hide = document.getElementById("myUL1");
targetSpan.addEventListener("click", function() {
hide.style.display = "none";
}, false);
span {
cursor: pointer;
}
<div>
<ul id="myUL1">
<li>list</li>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
<div>Clear list <span id="mySpan">X</span></div>
</div>
Related
hope you all doing great.
I've been trying to add the (active class )to each of the navbar links when the user is on that specific section of the page with this
Tutorial (i'm stuck at 2:45:05) and no success so far can anyone tell me what i did wrong .thank you.
const menu = document.querySelector(' nav .container ul');
const navItems = menu.querySelectorAll('li');
navItems.forEach(item => {
const link = item.querySelector('a');
ink.addEventListener('click', () => {
link.classList.add(".active");
});
});
nav .container ul li a.active {
background: var(--color-primary);
color: var(--color-white);
}
<nav>
<div class="container">
<a href="#">
<h3> AMANI DEV </h3>
</a>
<ul>
<li>Home</li>
<li>About</li>
<li>Skills</li>
<li>Services </li>
<li>Portfolio </li>
<li>Contact Me </li>
</ul>
</div>
</nav>
Typo with ink not link.
When you assign a class with classList you don't include the .: classList.add('active').
In your CSS background should probably be background-color.
If you want to remove the other active links before applying the new one you can use forEach to iterate over the links and use classList.remove('active') on each one.
You may find event delegation easier to manage. Rather than attaching multiple listeners to multiple elements attach one listener to the list element that watches out for events from its child elements as they "bubble up the DOM. You can then check that the clicked element is a link, remove the active classes from the previous link(s), and then apply the active class to the clicked link.
Here's an example using event delegation.
// Cache the list, and the items
const list = document.querySelector(' nav .container ul');
const links = list.querySelectorAll('a');
// Add one listener to the list element
list.addEventListener('click', handleClick);
// If the clicked element is a link remove all
// the active classes from the other links, and then
// add the active class to the link that was clicked on
function handleClick(e) {
if (e.target.matches('a')) {
links.forEach(link => link.classList.remove('active'));
e.target.classList.add('active');
}
}
:root { --color-white: white; --color-primary: red; }
.active {
background-color: var(--color-primary);
color: var(--color-white);
}
<nav>
<div class="container">
<a href="#">
<h3> AMANI DEV </h3>
</a>
<ul>
<li><a class="active" href="#home">Home</a></li>
<li>About</li>
<li>Skills</li>
<li>Services </li>
<li>Portfolio </li>
<li>Contact Me </li>
</ul>
</div>
</nav>
You need to do querySelectorAll in a tag not on the li tag. Just do this and do let me know.
Modify the code in the following line :
ink.addEventListener('click',() => {
to
link.addEventListener('click',() => {
to be like this
const menu = document.querySelector(' nav .container ul');
const navItems = menu.querySelectorAll('li');
navItems.forEach(item => {
const link = item.querySelector('a');
link.addEventListener('click',() => {
link.classList.add(".active");
});
});
document.querySelectorAll('ul li').forEach(el => {
el.onclick = () => {
document.querySelectorAll('ul li').forEach(el => el.classList.remove('active'));
el.classList.add('active');
}
})
here a demo code:
document.querySelectorAll('#myNav li').forEach(el => {
el.onclick = () => {
document.querySelectorAll('#myNav li').forEach(el => el.classList.remove('active'));
el.classList.add('active');
}
})
.active {
font-size: 70px;
}
<nav>
<div class="container">
<a href="#">
<h3> AMANI DEV </h3>
</a>
<ul id="myNav">
<li><a class="active" href="#home">Home</a></li>
<li>About</li>
<li>Skills</li>
<li>Services </li>
<li>Portfolio </li>
<li>Contact Me </li>
</ul>
</div>
</nav>
// selecting all a element on the page
const links = document.querySelectorAll('a');
// adding a click event on all elements
links.forEach((link) => {
link.addEventListener('click', (e) => {
// if we click first thing is deleting the active class from all link
links.forEach((link) => {
link.classList.remove('active')
})
// then in the end add the active class only in the correct one
e.target.classList.add('active')
})
})
This question already has answers here:
What do querySelectorAll and getElementsBy* methods return?
(12 answers)
Closed 1 year ago.
I want the navbar <ul> to disappear when I click it. With querySelectorAll() I selected all <li>s in the navbar. Then I added a click event listener to it. So when I click it, it should toggle the class of the navbar <ul> to "active" and then disappear.
It works with the toggle button but not with the <li>s.
<i id="togglebtn" class="fas fa-bars"></i>
<nav class="navbar">
<div class="brand-title">brandName</div>
<div class="navbar-links">
<ul id="ul">
<li class="jsscrolltrigger">Start</li>
<li class="jsscrolltrigger">Galerie</li>
<li class="jsscrolltrigger">Anfahrt</li>
<li class="jsscrolltrigger"><a href="#Speisekarte">Speisekarte</>
</li>
</ul>
</div>
</nav>
<script type="text/javascript">
var togglebtn = document.getElementById("togglebtn");
togglebtn.addEventListener("click", function () {
ul.classList.toggle("active");
});
// this following part doesnt work //
// i want the ul(navbar) to disappear when i click it //
var a = document.querySelectorAll(".jsscrolltrigger");
var ul = document.getElementById("ul");
a.addEventListener("click", function () {
ul.classList.toggle("active");
});
</script>
querySelectorAll returns a NodeList. You have to iterate the list and add the event listener to every node.
For example:
var togglebtn = document.getElementById("togglebtn");
togglebtn.addEventListener("click", function() {
ul.classList.toggle("active");
});
var nodeList = document.querySelectorAll(".jsscrolltrigger");
var ul = document.getElementById("ul");
nodeList.forEach(node => {
node.addEventListener("click", function() {
ul.classList.toggle("active");
});
})
<i id="togglebtn" class="fas fa-bars"></i>
<nav class="navbar">
<div class="brand-title">brandName</div>
<div class="navbar-links">
<ul id="ul">
<li class="jsscrolltrigger">Start</li>
<li class="jsscrolltrigger">Galerie</li>
<li class="jsscrolltrigger">Anfahrt</li>
<li class="jsscrolltrigger">Speisekarte</li>
</ul>
</div>
</nav>
When you use Document.querySelectorAll() It doesn't return a single element. It return a NodeList on which you can call forEach to loop through all of the item.
let a = document.querySelectorAll('.jsscrolltrigger');
let ul = document.getElementById("ul");
a.forEach(function(element) {
element.addEventListener('click', function(e){
e.preventDefault();
ul.classList.toggle("active");
});
});
.active {
border: 2px solid red;
}
<nav class="navbar">
<div class="brand-title">brandName</div>
<div class="navbar-links">
<ul id="ul">
<li class="jsscrolltrigger">Start</li>
<li class="jsscrolltrigger">Galerie</li>
<li class="jsscrolltrigger">Anfahrt</li>
<li class="jsscrolltrigger"><a href="#Speisekarte">Speisekarte</>
</li>
</ul>
</div>
</nav>
If you don't want to use forEach to perform the loop you can force the NodeList to be consider as an Array by passing it to the Array.from() method which allows you to perform any array operation on selected elements
Array.from(a).map(function(){ /*...*/ });
Array.from(a).filter(function(){ /*...*/ });
My first go at making my own mini webpage from scratch, specifically looking to understand how onmouseover/onmouseout works using .display.opacity. I would like to hover my mouse over each element and it displays text specified text while the rest of the webpage disappears. Hope I gave enough information first time using StackOverflow.
my first element works perfectly with the function created showHilton().
however my second element and function "showInnovel();" does not
I currently have 3 elements and would like this to work with all if possible
<ul>
<li onmouseover="showHilton();" onmouseout="showHilton();"class="hiltonGrand" id="HGV">Hilton Grand Vacations</li>
<li id="hilton" style="opacity:0; background: black; color: white; text-align:right;">hello</li>
<li onmouseover="showInnovel();" onmouseout="showInnovel();"class="in" id="inSol">Innovel Solutions</li>
<li id="iS" style="opacity:0; background: black; color: white; text-align:right;">innovel</li>
<li class="DR" id="Dr">Diamond Resorts</li>
<li id="diamond" style="opacity:0; background: black; color: white; text-align:right;">Diamond</li>
</ul>
</div>
<div>
<!--Back button-->
<!--Home Button-->
<!--Customer Service-->
</div>
<script type="text/javascript">
var hilton = document.getElementById("hilton");
var innovel = document.getElementById("inSol");
var Dr = document.getElementById("Dr");
var hGV = document.getElementById("HGV");
var iS = document.getElementById("iS");
function showHilton() {
if(hilton.style.opacity == 0){
//element.style.display = "block";
hilton.style.opacity= 1;
innovel.style.opacity = 0;
Dr.style.opacity=0;
} else {
//element.style.display = "none";
hilton.style.opacity=0;
innovel.style.opacity=1;
Dr.style.opacity=1;
}
}
function showInnovel() {
if(iS.style.visibility == 0){
//element.style.display = "block";
iS.style.opacity = 1;
hGV.style.opacity = 0;
Dr.style.opacity=0;
} else {
//element.style.display = "none";
iS.style.opacity=0;
hGV.style.opacity=1;
Dr.style.opacity=1;
}
}
Your current setup uses a HTML structure like so:
<ul>
<li>Toggle 1</li>
<li>Content 1</li>
<li>Toggle 2</li>
<li>Content 2</li>
</ul>
This makes it quite hard to toggle the next element, whichc would require some js as you've already stated in your question.
I would re-work the html, to something like:
<ul>
<li>
Toggle 1
<p>Content 1</p>
</li>
<li>
Toggle 2
<p>Content 2</p>
</li>
</ul>
This way we can use native css to toggle the display property on the child elements to get the desired output:
/* Hide */
li > p {
display: none;
background: black;
color: white
}
/* Show on hover */
li:hover > p {
display: block;
}
<div>
<ul>
<li class="hiltonGrand" id="HGV">
Hilton Grand Vacations
<p>hello</p>
</li>
<li class="in" id="inSol">
Hilton Grand Vacations
<p>innovel</p>
</li>
<li class="DR" id="DR">
Hilton Grand Vacations
<p>Diamond</p>
</li>
</ul>
</div>
<div>
<!--Back button-->
<!--Home Button-->
<!--Customer Service-->
</div>
How can i add a class to an <li> element which has a child <ul> element. I found there are so many examples in jQuery but not in Javascript. I would like to do it in Pure Javascript for Performance Optimization. The code is as follows: Thanks in Advance!
<nav id="navigation">
<li>Home</li>
<li> <!-- >>> I want to add a class to this <li> element as it has a <ul> child element -->
Services
<ul>
<li>Graphic Designing</li>
<li>Web Designing</li>
</ul>
</li>
<li>Contact</li>
</nav>
I think you need something like this
// -------- vanilla js
document.querySelectorAll('li').forEach((el) => {
if(el.querySelector('ul')) el.classList.add('theClassNameYouNeed');
});
// -------- jQuery (just to see the difference) :)
$('li').each(function() {
const el = $(this);
if(el.find('ul').length) el.addClass('theClassNameYouNeed');
});
Useful resources to move from jQuery to pure Javascript (Vanilla):
http://youmightnotneedjquery.com/
https://tobiasahlin.com/blog/move-from-jquery-to-vanilla-javascript/
https://gist.github.com/joyrexus/7307312
document.querySelectorAll('li').forEach((el) => {
if(el.querySelector('ul')) el.classList.add('theClassNameYouNeed');
});
.theClassNameYouNeed {
background: green;
}
<li>Home</li>
<li>
Services
<ul>
<li>Graphic Designing</li>
<li>Web Designing</li>
</ul>
</li>
<li>Contact</li>
This is one possible way of adding the class to the li element which has ul as child
const liElem = document.querySelectorAll("li")
liElem.forEach(elem => {
if(elem.querySelector("ul")) {
elem.classList.add("new-class");
}
})
.new-class {
color: red;
background: #ececec
}
<li>Home</li>
<li>
Services
<ul>
<li>Graphic Designing</li>
<li>Web Designing</li>
</ul>
</li>
<li>Contact</li>
Demo snippet
const liElems = document.querySelectorAll('li');
liElems.forEach((elem) => {
const childrenElems = elem.querySelectorAll('ul')
if(childrenElems.length > 0){
elem.setAttribute("class", "democlass")
}
});
<html>
<head></head>
<body>
<li>Home</li>
<li>
Services
<ul>
<li>Graphic Designing</li>
<li>Web Designing</li>
</ul>
</li>
<li>Contact</li>
<script src="script.js"></script>
<body>
</html>
You can do this two ways below using only JavaScript off-course.
Here is simple direct solution to add class to the li which has ul in it. This selects the first li > ul in the DOM and apply class to it using classList and add method.
Live Demo:
window.addEventListener('DOMContentLoaded', (event) => {
let getLiUL = document.querySelector('li > ul')
getLiUL.parentElement.classList.add('foo')
});
.foo {
background: green;
}
<nav>
<li>Home</li>
<li>I want to add a class to this element as it has a child element
Services
<ul>
<li>Graphic Designing</li>
<li>Web Designing</li>
</ul>
</li>
<li>Contact</li>
</nav>
Here is solution which uses querySelectorAll method and forEach loop. This loops through all the li in the DOM and apply class to the only li which has ul as a child.
Live Demo:
window.addEventListener('DOMContentLoaded', (event) => {
let getLiUL = document.querySelectorAll('li')
getLiUL.forEach(function(e) {
e.querySelector('ul') ? e.classList.add('foo') : " "
})
});
.foo {
background: green;
}
<nav>
<li>Home</li>
<li>I want to add a class to this element as it has a child element
Services
<ul>
<li>Graphic Designing</li>
<li>Web Designing</li>
</ul>
</li>
<li>Contact</li>
</nav>
References:
ClassList
querySelector
querySelectorAll
I'm currently trying to create a double-dropdown menu using JavaScript & HTML lists. I know there is a lot about it in the internet, but these solutions don't fit me or use jQuery (and I'm doing this for JavaScript practice mostly). I've created something like that:
JS Code:
function clear_id() {
document.getElementById("first").style.display = "none";
document.getElementById("second").style.display = "none";
}
function dropdown_id(id) {
var element = document.getElementById(id);
if (element.style.display === "block") {
element.style.display = "none";
} else {
clear_id();
element.style.display = "block";
}
}
function clear_class(element) {
for (var i = 0; i < element.length; ++i) {
element[i].style.display = "none";
}
}
function dropdown_class(id, num) {
var element = document.getElementsByClassName(id);
if (element[num].style.display === "block") {
element[num].style.display = "none";
} else {
clear_class(element);
element[num].style.display = "block";
}
}
CSS Code:
ol,
ul {
display: none;
}
#main {
display: block;
}
li {
list-style-type: none;
}
HTML Code:
<ol id="main">
<li>
First
<ul id="first">
<li>
fir
<ol class="one">
<li>f</li>
<li>s</li>
</ol>
</li>
<li>
sec
<ol class="one">
<li>f</li>
<li>s</li>
</ol>
</li>
</ul>
</li>
<li>
Second
<ul id="second">
<li>fir
<ol class="two">
<li>f</li>
<li>s</li>
</ol>
</li>
<li>
sec
<ol class="two">
<li>f</li>
<li>s</li>
</ol>
</li>
</ul>
</li>
</ol>
So at this point, I simply have to expand and roll (depending on display state) after click. Here is my solution for that problem.
It works fine, but I feel that it can be done simpler, just don't know JavaScript good enough and I'm blocked by my C++ approach (recently moved from C++ to web because of curiosity). So here is my question: can it be done easier and simpler(maybe more correct)? If anyone can show me the right path, I would be very grateful.
Here is another implementation, I pass in the DOM element using the this keyword which I then use in my javascript function. It is also a bit shorter than your solution but not necessarily better.
function toggle (el) {
if (el.childNodes[1].className === 'disappear') {
el.childNodes[1].classList.remove('disappear');
} else {
el.childNodes[1].classList.add('disappear');
}
}
.disappear {
display: none;
}
li:hover{
color:red
}
<ul>
<li onclick="toggle(this);">first
<ul class="disappear">
<li>1</li>
<li>2</li>
</ul>
</li>
<li onclick="toggle(this);">second
<ul class="disappear">
<li>1</li>
<li>2</li>
</ul>
</li>
</ul>
Hopefully this is helpful for you!