Pure JavaScript: toggle links active - javascript

My code is working only for first "a" child. Does not working on the rest "a" child. Why?
There are some solutions on the internet but in jQuery. I prefer pure JavaScript.
document.querySelector('a').addEventListener('click', active);
function active() {
document.querySelector('a').classList.remove('active');
this.classList.add('active');
}
.topnav {
overflow: hidden;
background-color: grey;
}
.topnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 10px;
text-decoration: none;
}
.topnav a:hover {
background-color: #ddd;
color: black;
}
.topnav a.active {
background-color: red;
color: white;
}
<div class="topnav">
<a class="active" href="#home">Home</a>
News
Contact
About
</div>

Add id instead of class; remove 'active' class on each click and then add 'active' class to clicked anchor tag;
document.getElementById('news').onclick = active;
document.getElementById('home').onclick = active;
document.getElementById('contact').onclick = active;
document.getElementById('about').onclick = active;
//addEventListener('click', active);
function active() {
document.querySelector('a.active').classList.remove('active');
this.classList.add('active');
}
.topnav {
overflow: hidden;
background-color: grey;
}
.topnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 10px;
text-decoration: none;
}
.topnav a:hover {
background-color: #ddd;
color: black;
}
.topnav a.active {
background-color: red;
color: white;
}
<div class="topnav">
<a class="active" id="home" href="#home">Home</a>
News
Contact
About
</div>

You can use event delegation with querySelectorAll to write small and neat solution like below:
document.querySelector('.topnav').addEventListener('click', active);
function active(e) {
document.querySelectorAll('.topnav > a').forEach(function(a){
a.classList.remove('active');
})
e.target.classList.add('active');
}
.topnav {
overflow: hidden;
background-color: grey;
}
.topnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 10px;
text-decoration: none;
}
.topnav a:hover {
background-color: #ddd;
color: black;
}
.topnav a.active {
background-color: red;
color: white;
}
<div class="topnav">
<a class="active" href="#home">Home</a>
News
Contact
About
</div>

You need querySelectorAll and some looping:
const menuItems = document.querySelectorAll('a');
menuItems.forEach(el =>
el.addEventListener('click', active)
);
function active() {
menuItems.forEach(el =>
el.classList.remove('active')
);
this.classList.add('active');
}

You should use document.querySelectorAll('a')

Related

How can I focus the onclick onto this icon? (HTML, CSS, JS)

I need help with figuring out how to focus the 'clicking' part of this dropdown navbar icon so that I don't have to click a little to the left of the icon (also the other navbar items) since I'm trying to recreate Mac OS's navbar.
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(e) {
if (!e.target.matches('.dropbtn')) {
var myDropdown = document.getElementById("myDropdown");
if (myDropdown.classList.contains('show')) {
myDropdown.classList.remove('show');
}
}
}
.navbar {
overflow: hidden;
background-color: #333;
font-family: Arial, Helvetica, sans-serif;
}
.navbar a {
float: left;
font-size: 12px;
color: white;
text-align: center;
padding: 10px 10px;
text-decoration: none;
}
.dropdown {
float: left;
overflow: hidden;
}
.dropdown .dropbtn {
cursor: pointer;
font-size: 12px;
border: none;
outline: none;
color: white;
padding: 5px 10px;
background-color: inherit;
font-family: inherit;
margin: 0;
}
<div class="dropdown">
<button class="dropbtn" onclick="myFunction()">
<i class="fa-solid fa-power-off"></i>
</button>
<div class="dropdown-content" id="myDropdown">
Link 1
Link 2
Link 3
</div>
</div>
IMG:
Problem
I found the source where OP came from and I am not surprised why you ran into trouble. W3Schools is a good resource because it's simple and never over explains things but at times it omits or just overlooks certain details. In the W3School example "Dropdown Menu Inside a Navigation Bar" the following segment of a CSS ruleset is wrong:
.dropbtn:focus {
background-color: red;
}
focus event only applies to the these tags:
<input>
<textarea>
<select>
<a>
It may vary between browsers but the above list is standard. So <button> is usually not focusable.
Solution
Change the <button> into an <a>
Add e.preventDefault(); to the event handler so the page won't jump when the <a> is clicked.
The rest of the changes are recommended, but not necessary. Although I strongly suggest that you don't use inline event handlers:
<button onclick="lame(this)">Don't do this</button>
Instead use:
// onevent property
document.querySelector('button').onclick = better;
OR
// event listener
document.querySelector('button').addEventListener('click', best);
const menu = document.querySelector("menu");
document.querySelector('.btn').onclick = toggleMenu;
function toggleMenu(e) {
e.preventDefault();
menu.classList.toggle("show");
}
window.onclick = function(e) {
if (!e.target.matches('.btn, .btn *') && menu.classList.contains('show')) {
menu.classList.remove('show');
}
}
html {
font: 300 2vmax/1.2 'Segoe UI';
}
nav {
display: flex;
overflow: hidden;
background-color: #333;
}
nav a {
display: block;
padding: 0.75rem 1.2rem;
color: white;
text-align: center;
text-decoration: none;
}
.dropdown {
min-width: 7.75rem;
overflow: hidden;
}
.btn {
display: flex;
justify-content: space-between;
align-items: center;
margin: 0;
padding: 0.75rem 1.2rem;
border: none;
outline: none;
color: white;
text-align: left;
}
.btn * {
display: block;
font-weight: 300;
}
.btn i {
padding-top: 0.15rem;
}
nav a:hover,
.btn:focus {
background-color: red;
}
menu {
position: absolute;
display: none;
min-width: 7.75rem;
margin: 0;
padding-left: 0;
background-color: #f9f9f9;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
}
menu a {
padding: 0.5rem 1.2rem;
text-align: left;
color: black;
}
menu a:hover {
background-color: #ddd;
}
.show {
display: block;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<nav>
Home
News
<div class='dropdown'>
<a href='#' class="btn"><b>Menu</b>
<i class="fa fa-chevron-circle-down"></i>
</a>
<menu>
Link 1
Link 2
Link 3
</menu>
</div>
</nav>

h3 won't display probably because of the navigation bar [duplicate]

This question already has answers here:
What is a clearfix?
(10 answers)
What methods of ‘clearfix’ can I use?
(29 answers)
Closed 2 years ago.
I wanted to create a web page, after making the navigation bar the h3 won't display probably I don't know why and this is what I am getting:
A screenshot of the output I'm getting
.Navigation {
width: 100%;
height: 30%;
float: center;
border: 2px solid black;
}
ul {
list-style-type: none;
}
li {
list-style-type: none;
}
a.Navi {
float: left;
}
li a {
color: black;
background-color: transparent;
text-align: center;
padding: 14px 16px;
}
li a:hover {
color: #B1AFAF;
}
.title {
text-align: left;
float: left;
}
<body>
<div class="Navigation">
<div class="items">
<li><a class="Navi">Page1</a></li>
<li><a class="Navi">Page2</a></li>
</div>
</div>
<br>
<div class="P1">
<h3 class="title">Ttile</h3>
</div>
</body>
How can I fix this bug?
You should add some styles to div tag (.P1) like below
.Navigation{
width:100%;
height:30%;
float: center;
border: 2px solid black;
}
ul {
list-style-type: none;
}
li {
list-style-type: none;
}
a.Navi{
float: left;
}
li a {
color: black;
background-color:transparent;
text-align: center;
padding: 14px 16px;
}
li a:hover {
color: #B1AFAF;
}
.P1{
float: left;
width: 100%;
text-align: left;
}
.title{
text-align: left;
float: left;
}
<div class= "Navigation">
<div class = "items">
<li><a class="Navi" >Page1</a></li>
<li><a class="Navi">Page2</a></li>
</div>
</div>
<br>
<div class = "P1">
<h3 class="title">Ttile</h3>
</div>
Simply, we need to add clearfix Hack..
Like this
.Navigation::after {
content: "";
clear: both;
display: table;
}
Learn More about Clearfix : https://www.w3schools.com/howto/howto_css_clearfix.asp

Need help toggling dropdown menus using the same class (Javascript)

I'm trying to get this to work for all elements using the class-name '.sub-menu-parent', but I can only get it to work for the first instance of it.
I have tried using a for loop with the index of parentClass, but it doesn't seem to work. Same goes with the '.sub-menu-child' class.
HTML
<nav>
<div class="row">
<img src="resources/img/logos/HTH_Logo_1_2.png" alt="A logo that says 'hearts that heal'" class="logo">
<ul class="main-nav">
<li>Home</li>
<li>About Us <i class="ion-android-arrow-dropdown"></i>
<ul class="drop-down-main sub-menu--child">
<li>Who We Are</li>
<li>Mission Statement</li>
<li>Vision Statement</li>
<li>Our Values</li>
<li>Goals</li>
<li>Objectives</li>
</ul>
</li>
<li>Photo Gallery <i class="ion-android-arrow-dropdown"></i>
<ul class="drop-down-main sub-menu--child">
<li>Group Photos</li>
<li>Retreat Photos</li>
<li>Members Photos</li>
<li>Honorary Members Photos</li>
<li>Our Beloved Children</li>
<li>Activities and Sponsorship Photos</li>
</ul>
</li>
<li>Contact</li>
</ul>
</div>
</nav>
CSS
/* ----- MAIN NAV ----- */
.main-nav {
float: right;
list-style-type: none;
margin-top: 32.5px;
}
.main-nav li {
display: inline;
text-align: center;
}
.main-nav li a:link,
.main-nav li a:visited {
text-decoration: none;
color: #fff;
padding: 5px 10px;
font-weight: 400;
font-size: 80%;
background-color: #c95a6c; /* #484066 */
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.main-nav li a:hover,
.main-nav li a:active {
background-color: #fff;
color: #c95a6c;
}
/* ----- For colors ----- */
.main-nav-color:focus {
color: #c95a6c !important;
background-color: #fff !important; /* #484066 */
}
/* ----- NESTED NAV ----- */
.drop-down-main {
position: absolute;
z-index: 9990;
background-color: #fff;
display: none;
margin-top: 5px;
border: 1px solid #484066;
border-top: none;
}
.show {
display: block;
}
.drop-down-main li {
display: block;
text-align: left;
border-bottom: 1px solid #484066;
width: 100%;
}
.drop-down-main li a:link,
.drop-down-main li a:visited {
display: block;
text-decoration: none;
color: #c95a6c;
font-weight: 400;
font-size: 80%;
background: none; /* #484066 */
border-radius: 0;
padding: 5px 24px 5px 5px;
}
.drop-down-main li:hover,
.drop-down-main li:active {
background-color: #c95a6c;
}
.drop-down-main li a:hover,
.drop-down-main li a:active {
color: #fff;
}
.drop-down-main li:first-child {
margin-top: 10px;
border-top: 1px solid #484066;
}
.drop-down-main li:last-child {
border: none;
}
Javascript
var menuToggle = (function() {
var DOMstrings = {
displayToggle: 'show',
dropParent: '.sub-menu--parent',
dropChild: '.sub-menu--child',
colorToggle: 'main-nav-color',
};
var parentClass = document.querySelector(DOMstrings.dropParent);
var childClass = document.querySelector(DOMstrings.dropChild);
parentClass.addEventListener('click', toggleDropdown, false);
function toggleDropdown() {
childClass.classList.toggle(DOMstrings.displayToggle);
parentClass.classList.toggle(DOMstrings.colorToggle);
};
window.addEventListener('click', function(event) {
if(event.target !== parentClass && event.target.parentNode !== parentClass) {
childClass.classList.remove(DOMstrings.displayToggle);
parentClass.classList.remove(DOMstrings.colorToggle);
}
});
})();
I have also tried using querySelectorAll but it seems you can't use classList Methods with it.
You should use querySelectorAll
Based from this answer: Add event listener to DOM elements based on class
document.querySelector('.class-name'); Will only select the first element having class='class-name'.
For adding event listener to all such elements, use querySelectorAll()
And then update the code where you attach the listener.
var parentClasses = document.querySelectorAll(DOMstrings.dropParent);
for (var i = 0; i < parentClasses.length; i++) {
parentClasses[i].addEventListener('click', setupEventListener(parentClasses[i]), false);
}
function setupEventListener(element){
return function(){
toggleDropdown(element);
}
}
function toggleDropdown(element) {
// since `ul` is a sibling of `a`
element.nextElementSibling.classList.toggle(DOMstrings.displayToggle);
element.classList.toggle(DOMstrings.colorToggle);
};
I believe this should work for your current implementation, however this doesn't include code for toggling the display off.

How to use animation with append in jQuery?

How to use animation while appending new element using jQuery? I went through couple of answers here but the same method does not work for me. I used show('show') and fadeIn('slow') but it does not seem that animates the new element.
$(document).ready(function() {
$('#add-item').click(add);
function add() {
var newItem = $('#new-item-text');
var span = $('<span>', {
class: 'remove',
click: remove
});
var li = $('<li>', {
class: 'todo-item',
text: newItem.val(),
append: span,
click: completed
});
if (newItem.val()) {
$('ul.todo-list').append(li, $('li.todo-new')).fadeIn('slow');
newItem.val('');
}
}
});
.todo-list {
list-style: none;
padding: 0px;
}
.todo-item {
border: 2px solid #444;
margin-top: -2px;
padding: 10px;
cursor: pointer;
display: block;
background-color: #ffffff;
}
.todo-new {
display: block;
margin-top: 10px;
}
.todo-new input[type='text'] {
width: 260px;
height: 22px;
border: 2px solid #444;
}
.todo-new a {
font-size: 1.5em;
color: black;
text-decoration: none;
background-color: #ffffff;
border: 2px solid #444;
display: block;
width: 24px;
float: right;
text-align: center;
}
.todo-new a:hover {
background-color: #0EB0dd;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<ul class='todo-list'>
<li class='todo-item'>4L 2% Milk
<span class='remove'></span>
</li>
<li class='todo-item'>Butter, Unsalted
<span class='remove'></span>
</li>
<li class='todo-new'>
<input id='new-item-text' type='text' />
<a id='add-item' href='#'>+</a>
</li>
</ul>
To animate, you should start by hiding the elements, for instance by setting:
display: none;
Then fadeIn() will animate and set display: block;

HTML/CSS current active menu does not show active

please see https://jsfiddle.net/qvh5jsc4/1/
I was thinking job of the
li a:hover:not(.active) {
background-color: #111;
}
to reset none active color. But this is not working. Home link stays green.
So how to make the active link shows as green.
I have the following code:
CSS
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
li {
float: left;
}
li a {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
li a:hover:not(.active) {
background-color: #111;
}
.active {
background-color: #4CAF50;
}
HTML
<ul>
<li><a class="active" href="#home">Home</a></li>
<li>News</li>
<li>Contact</li>
<li>About</li>
</ul>
try this using jquery : https://jsfiddle.net/xqyhwq36/3/
li a:hover:not(.active) {
background-color: #111!important;
}
li a:hover {
background-color: #444;
}
.active {
background-color: #4CAF50;
}
$("ul a").click(function(){
$("ul a").removeClass("active");
$(this).addClass("active");
});
Take a look at this:
li a:not(.active):hover {
background-color: #111;
}
li a.active:hover {
background-color: #444;
}
First the id/class selector then the state selector.
A simple tweak in your CSS should do the trick.
li:hover {
background-color: #111!important;
}
li a.active:hover {
background-color: #444!important;
}

Categories

Resources