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
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>
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
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 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;
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;
}