I have a sidebar with site pages. I want to change the color of a currently selected page when clicked, assign the class is-active to the currently selected item, and remove it from all the others.
Here is the HTML:
<aside id="side-bar" class="sidebar">
<h3>Pages</h3>
<nav class="menu">
<a onclick="changeColor()" class="menu-item is-active">page 1</a>
<a onclick="changeColor()" class="menu-item">page 2</a>
<a onclick="changeColor()" class="menu-item">page 3</a>
</nav>
</aside>
And CSS:
.sidebar .menu .menu-item:hover,
.sidebar .menu .menu-item.is-active {
color: #f1672c;
border-right: 6px solid #f1672c;
}
Each element has the function change color that should take all the elements, remove the is-active class from previous selected element and add to the curent clicked element.
function changeColor(){
var links = document.getElementsByClassName("menu-item")
links.map(classList.remove("is-active"))
this.classList.add("is-active")
}
What am I missing?
That changeColor() is not necessary....
const pages = document.querySelectorAll(".menu-item");
pages.forEach((item) => {
item.addEventListener('click', active_item);
})
function active_item () {
pages.forEach((item) => {
item.classList.remove('is-active');
});
this.classList.add('is-active');
}
.is-active {
background-color: red;
}
<aside id="side-bar" class="sidebar">
<h3>Pages</h3>
<nav class="menu">
<a class="menu-item is-active">page 1</a>
<a class="menu-item">page 2</a>
<a class="menu-item">page 3</a>
</nav>
</aside>
Just pass the reference of current element with this.
function changeColor(el){
document.querySelector(".menu-item.is-active").classList.remove("is-active")
el.classList.add("is-active")
}
.sidebar .menu .menu-item:hover,
.sidebar .menu .menu-item.is-active {
color: #f1672c;
border-right: 6px solid #f1672c;
}
<aside id="side-bar" class="sidebar">
<h3>Pages</h3>
<nav class="menu">
<a onclick="changeColor(this)" class="menu-item is-active">page 1</a>
<a onclick="changeColor(this)" class="menu-item">page 2</a>
<a onclick="changeColor(this)" class="menu-item">page 3</a>
</nav>
</aside>
Related
I have a menu which opens up a submenu on click.
If a link has a dropdown menu (has class header--has-submenu), then on click, I'm making another element (.header__subContainer) appear.
The issue I'm having is with the logic. For example, in my demo, I have two links, what we deliver and about us, both have submenus.
I want a user to be able to click onto a link to open it and then click on the same link to close it (standard UX).
However, I also want the user to be able to click on one link (let's say 'what we deliver) and then click onto about usto show that menus dropdown (then the user can click theabout us` link again to close the menu).
I've tried toggleClass but this causes issues with the last scenario above.
Here's a demo:
$(".header--has-submenu a.header__parentLink").click(function(e) {
e.preventDefault();
console.log("click");
var id = $(this).attr('data-menu');
// add active state styles to link to showcase which menu is open
$("li.header--has-submenu").removeClass("header--has-submenu--active");
$(this).parent().addClass("header--has-submenu--active");
// open subContainer (black div that contains all submenus)
if ( $(".header__subContainer-menu").hasClass("header__subContainer-menu--active") ){
$(".header__subContainer").removeClass("header__subContainer--active");
} else {
$(".header__subContainer").addClass("header__subContainer--active");
}
// remove active class from submenu, so only one menu is open at one time
$(".header__subContainer-menu").removeClass("header__subContainer-menu--active");
// open the relevant menu
$(this).closest(".header__subContainer").addClass("header__subContainer--active");
$(".header__subContainer-menu[data-menu='"+id+"']").toggleClass("header__subContainer-menu--active");
});
.header {
padding: 30px 0;
}
.header__parentUl * {
color: #FFFFFF;
}
.header__li {
margin: 0 20px;
}
.header__subContainer {
display: none;
}
.header__subContainer--active {
display: block;
}
.header__subContainer-menu {
display: none;
}
.header__subContainer-menu--active {
display: block;
}
.header--has-submenu--active a {
color: green;
}
.background--black {
background: #000000;
}
.reset-list {
list-style-type: none;
margin: 0;
padding: 0;
}
.color--white {
color: #FFFFFF;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<header class="header background--black">
<div class="container">
<div class="col-xl-9 justify-content-end">
<nav class="header__menu">
<ul class="header__parentUl d-flex reset-list">
<li class="header__li header--has-submenu">
<a class="header__parentLink" href="#" data-menu="what-we-deliver">What we deliver</a>
</li>
<li class="header__li header--has-submenu">
<a class="header__parentLink" href="#" data-menu="about-us">About us</a>
</li>
</ul>
</nav>
</div>
</div>
<div class="container-fluid background--black header__subContainer">
<div class="row justify-content-center">
<div class="col-12">
<nav class="header__subContainer-menu" data-menu="what-we-deliver">
<ul class="header__subContainer-ul d-flex reset-list">
<li class="header__subContainer-li">
<a class="header__subContainer-link color--white " href="#">Link 1</a>
</li>
<li class="header__subContainer-li">
<a class="header__subContainer-link color--white " href="#">Link 2</a>
</li>
</ul>
</nav>
<nav class="header__subContainer-menu" data-menu="about-us">
<ul class="header__subContainer-ul d-flex reset-list">
<li class="header__subContainer-li">
<a class="header__subContainer-link color--white " href="#">Link 3</a>
</li>
<li class="header__subContainer-li">
<a class="header__subContainer-link color--white " href="#">Link 4</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</header>
Something like this should work:
$(".header--has-submenu a.header__parentLink").click(function(e) {
e.preventDefault();
let id = $(this).attr('data-menu');
// Check if link already active
let wasOpen = $(this).parent().hasClass("header--has-submenu--active");
// remove all active classes
$(".header--has-submenu").removeClass("header--has-submenu--active");
$(".header__subContainer-menu").removeClass("header__subContainer-menu--active");
$(".header__subContainer").removeClass("header__subContainer--active");
if(!wasOpen){
// the clicked link was not open
// add active classes to the 3 elements
$(this).parent().addClass("header--has-submenu--active");
$('.header__subContainer').addClass('header__subContainer--active');
$(".header__subContainer-menu[data-menu='"+id+"']").addClass("header__subContainer-menu--active");
}
});
I'm trying to make a navigation bar with links.
I have it at the moment that upon hover, the colour of the text changes, and I'm trying to make it that when a navigation is clicked, it stays a colour while on that page, and then change the colour again when the next one is clicked.
My current script is:
$('span').click(function(){
$('span').removeClass("active");
$(this).addClass("active");
});
span.active {
color: #000000;
background-color:red;
}
#navshow1:hover, #navshow2:hover, #navshow3:hover {
color: #4532e3;
text-shadow: -0.06ex 0 #4532e3, 0.06ex 0 #4532e3;
}
<div class='navbarr'>
<li>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class ='active'><a href="#home" class="current" id='navshow1'>home</a></span>
<span><a href="#whatis" class="current" id='navshow2'>what is this site?</a></span>
<span> <a href="#test" class="current" id='navshow3'>test</a> </span>
</li>
</div>
I want exactly what is happening with the background colour, just for the text colour to stay dark purple while active. I don't know why its not working!!
From an HTML perspective, you can't have an li without it being a child of an ol or ul. Additionally, the span elements are redundant because they are just inline elements like the a element is, so all you really need is the a elements (or the actual li elements that hold the a elements). Then, you wouldn't need any JavaScript at all as you would just use :focus CSS pseudo-class.
/* Correct way to use lists but display as horizontal nav bars */
ul{ list-style-type:none; padding:0; }
li{ display:inline-block; }
.current:hover {
color: #4532e3;
text-shadow: -0.06ex 0 #4532e3, 0.06ex 0 #4532e3;
}
.current:focus {
color: #fff;
background-color:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Use <nav> instead of <div> for better semantics
and make each link be its own list item. -->
<nav class='navbar'>
<ul>
<li>
<a href="#home" class="current" id='navshow1'>home</a>
</li>
<li>
<a href="#whatis" class="current" id='navshow2'>what is this site?</a>
</li>
<li>
<a href="#test" class="current" id='navshow3'>test</a>
</li>
</ul>
</nav>
$('span').click(function() {
$('span').removeClass("active");
$(this).addClass("active");
});
span.active>a {
color: white;
background-color: red;
}
a {
text-decoration: none;
}
#navshow1:hover,
#navshow2:hover,
#navshow3:hover {
color: #4532e3;
text-shadow: -0.06ex 0 #4532e3, 0.06ex 0 #4532e3;
}
<div class='navbarr'>
<li>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class='active'><a href="#home" class="current" id='navshow1'>home</a></span>
<span><a href="#whatis" class="current" id='navshow2'>what is this site?</a></span>
<span> <a href="#test" class="current" id='navshow3'>test</a> </span>
</li>
</div>
I just want to ask :
how to make the dropdown-menu collpase when the dropdown menu is active?
When the mouse hovers to the sidebar, the active dropdown menu expanded again?
i think i just wondering using hover but it doesnt work when i try it, so i hope someone can help me to solve this?
Simple Concept I Just want :
Mouse:hover to sidebar-icon/burger is clicked => sidebar-expanded => menu list that have:submenu clicked => dropdown-menu displayed => mouseOut from sidebar => icon is-collapsed
Mouse:hover to sidebar-icon again / sidebar:state(active) => dropdown menu is already expanded
well i dont know that you can understand my question or something.. but i hope u can make this auto collapse menu
$(document).ready(function() {
// Sidebar links
$('.sidebar .side-list li a').on('click', function() {
const $this = $(this);
if ($this.parent().hasClass('buka')) {
$this
.parent()
.children('.dropdown-menu')
.slideUp(200, () => {
$this.parent().removeClass('buka');
});
} else {
$this
.parent()
.parent()
.children('li.buka')
.children('.dropdown-menu')
.slideUp(200);
$this
.parent()
.parent()
.children('li.buka')
.children('a')
.removeClass('buka');
$this
.parent()
.parent()
.children('li.buka')
.removeClass('buka');
$this
.parent()
.children('.dropdown-menu')
.slideDown(200, () => {
$this.parent().addClass('buka');
});
}
});
// ٍSidebar Toggle
$('.burger').on('click', e => {
$('.konten').toggleClass('k-kebuka');
$('.sidebar').toggleClass('s-kebuka');
e.preventDefault();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="sidebar" class="sidebar bg-cerah">
<div class="sidebar-dalem">
<div class="side-konten">
<ul class="side-list">
<li class="side-item dropdown">
<a class="dropdown-toggle" href="javascript:void(0)">
<span class="side-ikon">ICON</span>
<span class="side-judul">MENU</span>
<span class="panah">[>]</span>
</a>
<ul class="dropdown-menu">
<li>
SUBMENU #1
</li>
<li>
SUBMENU #2
</li>
</ul>
</li>
<li class="side-item dropdown">
<a class="dropdown-toggle" href="javascript:void(0)">
<span class="side-ikon">[X]</span>
<span class="side-judul">MENU #2</span>
<span class="panah">[>] ></span>
</a>
<ul class="dropdown-menu">
<li>
SUBMENU #1
</li>
<li>
SUBMENU #2
</li>
</ul>
</li>
<li class="side-item">
<a class="side-link" href="javascript:void(0)">
<span class="side-ikon">[X]</span>
<span class="side-judul">MENU #3</span>
</a>
</li>
</ul>
</div>
</div>
</div>
<div id="konten" class="konten">
<div class="konten-navbar sticky-top">
<ul class="navbar-kiri">
<li>
<a id="burger" href="javascript:void(0)" class="burger">BURGER ICO</a>
</li>
<li>
SEARCH ICO
</li>
</ul>
</div>
</div>
In pure CSS, .menu:hover definitely works, but you have to build the entire menu inside of the element that has the :hover pseudo class and also either touching or overlapping:
.popup {
position: relative;
}
button {
width: 8em;
height: 40px;
}
ul {
position: absolute;
top: 36px;
left: 8px;
background: #eee;
border: 1px solid black;
display: none;
margin: 0;
width: 14em;
min-height: 8em;
padding: 0.5em;
list-style: none;
}
.popup:hover ul {
display: block;
}
<div>
<div class="popup"><button>Menu</button>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
</div>
Certainly, you'd need to style everything properly.
I also seem to remember that JQuery has OnMouseEnter and OnMouseLeave events that work kind of like :hover too.
How do I exclude the first element in a list from being targeted by a :hover selector?
CSS:
.navbar .navbar-nav > li :hover {
color:red !important;
}
HTML:
<li>
#Html.ActionLink("Login", "Login", "Home", new { area = "" }, new
{#class ="navbar-item" })
</li>
What I have tried so far:
document.getElementsByClassName("navbar-item")[0].onmouseover = function () {
mouseOver()
};
function mouseOver() {
document.getElementsByClassName("navbar-item")[0].style.color="blue !important"
}
You dont need to use JavaScript/jQuery for this. Just use the :nth-child css selector like this:
/* target all hovered li elements except the first one */
.navbar .navbar-nav > li:nth-child(n+2) a:hover {
color: red;
}
<nav class="navbar">
<ul class="navbar-nav">
<li>
<a class="nav-link" href="#">Link 1</a>
</li>
<li>
<a class="nav-link" href="#">Link 2</a>
</li>
<li>
<a class="nav-link" href="#">Link 3</a>
</li>
</ul>
</nav>
Or if you're not using the default bootstrap anchor links and just want to target the li element itself, just chain the :nth-child selector and the :hover selector like this:
/* target all hovered li elements except the first one */
.navbar .navbar-nav > li:nth-child(n+2):hover {
color: red;
}
<nav class="navbar">
<ul class="navbar-nav">
<li>
Link 1
</li>
<li>
Link 2
</li>
<li>
Link 3
</li>
</ul>
</nav>
You could also use not().
/* target all hovered li elements except the first one */
.navbar .navbar-nav > li:not(:first-child):hover {
color: red;
}
<nav class="navbar">
<ul class="navbar-nav">
<li>
Link 1
</li>
<li>
Link 2
</li>
<li>
Link 3
</li>
</ul>
</nav>
I have created expandable links where the arrow changes when you expand the link. Expandable works great and the arrow keeps changing correctly when I expand the other link. It doesn't switch correctly if I expand the same link.
Here is a demo.
HTML
<ul class="side-expand">
<li class="expandor">
<a class="adobe" href="#" id="vid_link3">Adobe Digital Editions</a>
<ul>
<li>
<a href="#" id="link22"><i class="icon-video"></i>
Introduction</a>
</li>
</ul>
</li>
<li class="expandor">
<a class="android" href="#" id="vid_link4">Android</a>
<ul>
<li>
<a href="#" id="link29"><i class="icon-video"></i>
Introduction</a>
</li>
</ul>
</li>
</ul>
JAVASCRIPT
$('.expandor > a:first-child').click(function(e) {
e.preventDefault();
var $this = $(this).next('ul');
$(".side-expand li ul").not($this).slideUp();
$this.slideToggle();
$('.side-expand > li').css('background-color', 'transparent');
$('.side-expand > li').removeClass('dexpandor');
var visibleUL = $('.side-expand li').find('ul').is(':visible');
if (visibleUL) {
$(this).parent('li').css('background-color', 'transparent', 'font-weight', 'normal').addClass('dexpandor');
}
});
arrow not changing for the same toggle
Replacing lines 8 through 13 with the following should toggle your arrow class properly:
$(this).parent().siblings().removeClass('dexpandor');
$(this).parent().toggleClass('dexpandor');
Add the class change code in slideToggle() callback. Because the ul is hidden only when slide is complete, which is when you need to remove the class.
DEMO
$('.expandor > a:first-child').click(function(e) {
e.preventDefault();
var $this = $(this).next('ul');
$(".side-expand li ul").not($this).slideUp();
$this.slideToggle(function() {
$('.side-expand > li').css('background-color', 'transparent');
$('.side-expand > li').removeClass('dexpandor');
var visibleUL = $(this).closest('li').find('ul').is(':visible');
if (visibleUL) {
$(this).parent('li').css('background-color', 'transparent', 'font-weight', 'normal').addClass('dexpandor');
}
});
});
.side-expand li ul {
display: none;
}
.expandor {
background-image: url("https://odhelp.blob.core.windows.net/content/artifacts/img/right-arrow-small.png");
}
.expandor,
.dexpandor {
background-color: transparent;
background-position: right 13px;
background-repeat: no-repeat;
}
.dexpandor {
background-image: url("https://odhelp.blob.core.windows.net/content/artifacts/img/down-arrow-small.png");
}
.side-expand li a {
font-size: 14px;
font-weight: normal;
padding-left: 70px;
}
.side-expand li a {
background-size: 25px auto !important;
border-bottom: 1px solid rgb(235, 235, 235);
color: #000;
display: block;
font-size: 15px;
padding: 5px 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="side-expand">
<li class="expandor">
<a id="vid_link3" value="6plk07k8op" href="#" class="adobe">Adobe Digital Editions</a>
<ul>
<li><a value="6plk07k8op" href="#" id="link22"><i class="icon-video"></i> Introduction</a></li>
<li><a value="q1kogk5dc2" href="#" id="link23"><i class="icon-video"></i> Install</a></li>
<li><a value="zmdge1whxu" href="#" id="link24"><i class="icon-video"></i> Authorize your computer</a></li>
<li><a value="snl5pnvv27" href="#" id="link25"><i class="icon-video"></i> Read eBooks</a></li>
<li><a value="8ldljcbtw0" href="#" id="link26"><i class="icon-video"></i> Return eBooks </a></li>
<li><a value="tfrp7xjgus" href="#" id="link27"><i class="icon-video"></i> Transfer eBooks to reader </a></li>
<li><a value="men1mw9an3" href="#" id="link28"><i class="icon-video"></i> Remove eBooks from reader</a></li>
</ul>
</li>
<li class="expandor">
<a id="vid_link4" value="ayfssj4211" href="#" class="android">Android</a>
<ul>
<li><a value="ayfssj4211" href="#" id="link29"><i class="icon-video"></i> Introduction </a></li>
<li><a value="aqv1ieh6zd" href="#" id="link30"><i class="icon-video"></i> Install the OverDrive app</a> </li>
<li><a value="ospa26ccnh" href="#" id="link37"><i class="icon-video"></i> Return and share titles</a></li>
</ul>
</li>
</ul>
Add this to the click event, it toggle the class :
$(this).parent('li').css('background-color','transparent', 'font-weight', 'normal').toggleClass('dexpandor','expandor');
Demo : jsfiddle