Changing text colour in navigation while page clicked not working - javascript

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>

Related

Best way to change navbar dropdown function from CSS-only to Javascript on mobile?

Here is my current CSS-only dropdown menu html:
<div class="main-nav">
<div class="main-nav-container">
<div class="nav-links">
<ul>
<li class="nav-link"><a>Nav Link</a>
<div class="dropdown">
<ul class="dropdown-list-type">
<li>
<ul>
<li>
Option
</li>
<li>
Option
</li>
<li>
Option
</li>
</ul>
</li>
</ul>
</div>
</li>
<li class="nav-link"><a>Nav Link</a>
<div class="dropdown">
<ul class="dropdown-list-type">
<li>
<ul>
<li>
Option
</li>
<li>
Option
</li>
<li>
Option
</li>
</ul>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
</div>
Relevant CSS:
.dropdown{
position: absolute;
display: flex;
top: 100%;
border-top: solid 1px var(--white-3);
left: 0;
z-index: 8;
opacity: 0;
pointer-events: none;
transition: .3s; }
.nav-link:hover > .dropdown,
.dropdown-link:hover > .dropdown{
transform: translate(0, 0);
opacity: 1;
pointer-events: auto;
}
On mobile, I want the user to be able to open and close the dropdown by tapping on the "Nav Link". Currently, the user can tap to open, but then has to tap somewhere else to close the dropdown. I figure I need Javascript make it do what I want.
My idea:
Use a media query to remove the hover function on mobile
Use Javascript to add a class to the "Nav Links" on mobile
Using this class, with JS, make the Nav Links toggle the dropdown to display/hide
Is this the best way to do it? If so, how do I add a class to the "Nav Links" with Javascript at a specific screen size?
I would like to just use plain Javascript, no Jquery.
Also, I current want to keep the CSS-only hover approach for desktop. So I want the Javascript function only for the mobile view.
I hope that makes sense to everyone. Thank you!

JS logic: Open / close menu on click or replace with another

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

Creating a dropdown menu with CSS and JS

I am having trouble creating a simple dropdown menu nested inside the navigation bar. I have it so that when you hover over the navigation link dropdown appears, however, it disappears when you move down into the box- you can't. I want to be able to navigate in the dropdown box. I have been trying to do this with CSS and recently have tried with JS (though I am very new with JS so sorry, bear with me) I am having trouble understanding how to connect and apply a CSS class with JS so that it only works when you want it to.
const dropdown = document.querySelector('.second-nav-list-wrapper')
dropdown.onmouseenter = () => {
dropdown.classList.toggle('second-nav-list')
}
.second-nav{
position:relative;
}
.second-nav-list{
visibility:hidden;
list-style:none;
font-family:'Raleway';
text-transform:uppercase;
color:grey;
position:absolute;
top:10px;
background-color:rgb(235, 245, 252);
text-align:left;
padding:10px;
line-height: 40px;
display:flex;
}
.second-nav-link{
text-decoration:none;
color:rgb(59, 53, 53);
}
.header-nav-link-dropdown:hover .second-nav .second-nav-list{
visibility:visible;
text-decoration:none;
background-color:rgb(208, 215, 230);
}
<nav class="header-wrapper">
<ul class= "header-nav">
<li class="header-nav-link-wrapper">
Home
</li>
<li class="header-nav-link-wrapper header-nav-link-dropdown">
Recipes
<nav class="second-nav">
<ul class="second-nav-list">
<div class= "second-nav-list-wrapper">
<li>
Breakfast
</li>
<li>
Lunch
</li>
<li>
Snacks
</li>
<li>
Dinner
</li>
</div>
</ul>
</nav>
</li>
<li class="header-nav-link-wrapper">
Cookbooks
</li>
here's one way to do it. We use the onmouseover to open the dropdown. We use the onmouseleave event to close it. Note we are using onmouseleave on the whole navbar so we only close the dropdown when the mouse leaves the navbar and all it's children.
Here are also some examples of how other mouse hover events behave:
https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_onmousemove_leave_out
https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_onmousemove_over_enter
const dropdown = document.querySelector('.second-nav-list');
const recipies = document.querySelector('.recipies');
const navbar = document.querySelector('.header-nav')
//this function toggles visibiltity on
recipies.onmouseover = () => {
dropdown.style.visibility = "visible";
}
//this one toggles it off
navbar.onmouseleave = () => {
dropdown.style.visibility = "hidden";
}
.second-nav{
position:relative;
}
/* added background color here, removed the on-hover */
.second-nav-list{
visibility:hidden;
list-style:none;
font-family:'Raleway';
text-transform:uppercase;
color:grey;
position:absolute;
top:10px;
text-align:left;
padding:10px;
line-height: 40px;
display: block;
background-color:rgb(208, 215, 230);
color:rgb(59, 53, 53);
}
<nav class="header-wrapper">
<ul class= "header-nav">
<li class="header-nav-link-wrapper">
Home
</li>
<li class="header-nav-link-wrapper header-nav-link-dropdown">
Recipes <!-- Changed -->
<nav class="second-nav">
<ul class="second-nav-list">
<li>
Breakfast
</li>
<li>
Lunch
</li>
<li>
Snacks
</li>
<li>
Dinner
</li>
</ul>
</nav>
</li>
<li class="header-nav-link-wrapper">
Cookbooks
</li>
</ul>
</nav>

how to start the dropdown from the border of the menu bar instead of showing directly below the text

I have created the fiddle for the menu-header section for my webpage. I have made it by seeing this image. Once I click PROGRAMS and WORLD OF NORTHMAN, it should dropdown and show elements but it should only start the dropdown from the border of that header and that is I am not able to make it work.
Below is my HTML code:
<div class="topnav">
<img src="https://s4.postimg.org/ojd13poal/northman_wordmark_CMYK.png">
<nav>
<ul>
<li class="dropdown">
<b>PROGRAMS</b> <i class="fa fa-angle-down"></i>
<ul class="dropdown-content">
<li><i>INDIVIDUAL</i>
</li>
<li><i>CORPORATE</i>
</li>
</ul>
</li>
<li class="dropdown">
<b>WORLD OF NORTHMAN</b> <i class="fa fa-angle-down"></i>
<ul class="dropdown-content">
<li><i>BE EXTRODINARY</i>
</li>
<li><i>RISK & REWARD</i>
</li>
<li><i>BLOG</i>
</li>
<li><i>OUR STORY</i>
</li>
</ul>
</li>
</ul>
</nav>
</div>
How can I make sure that dropdown starts from the border of that menu instead coming directly from each of those text?
Try adding margin-top: 14px to the .topnav ul > li > ul selector:
.topnav ul > li > ul {
display: none;
margin-top: 14px;
width: 200px;
padding: 0;
position: absolute;
background-color: #f76c38;
}
https://jsfiddle.net/2nv4dd2w/15/
As a plus, if you want to close other opened menus: https://jsfiddle.net/2nv4dd2w/16/
Just add this
.dropdown-content{ margin-top:14px; }
You need to add the padding to .topnav a rather than .topnav ul > li. https://jsfiddle.net/2nv4dd2w/14/. This is because the ul html tag sits below the a html tag. If you want to keep the background-color the same size, use margin for the a tag, instead of padding, but I think it looks better with padding in my opinion :)
EDIT: Updated fiddle with inline-block image and navigation. https://jsfiddle.net/2nv4dd2w/19/. This should get you close to what you want. The rest is up to you. Happy Coding.

highlight currently selected link in css menu bar

I have a page with this URL: http://localhost:8000/progress/c/?l=1&c=1
And the below content to work as a simple css menu bar.
<div class="menu_div">
<ul>
<li> l1c1 </li>
<li> l1c1 </li>
<li> l1c1 </li>
<li> l1c1 </li>
</ul>
</div>
CSS styling is
.menu_div ul
{
padding:6px;
margin:0px;
font-size:12px;
list-style:none;
text-indent:15px;
}
.menu_div ul li
{
line-height:28px;
border-bottom:1px solid #000;
}
.menu_div ul li a
{
text-decoration:none;
font-color:#3A332D;
display:block;
}
.menu_div ul li a:hover
{
background:blue;
}
.menu_div ul li#active
{
background:blue;
}
When I hover over the links the background color changes but the currently selected menu link is not highlighted in blue.
I'm using django framework.
Try this jQuery code, it will add the class automatically
$(function(){
var url = window.location.href;
$("#menu a").each(function() {
if(url == (this.href)) {
$(this).closest("li").addClass("active");
}
});
});
In your CSS you have a class with the id 'active', this should probably be a class like this:
.menu_div ul li.active
{
background:blue;
}
Further, I wouldn't recommend trying to match the 'active' or better formulated 'current' page using javascript client side.
Instead your script on the server should recognize the current page and add a class to the related menu item so it would look like this:
<li class="active"> l1c1 </li>
Replace your id #active to class .active - that is more right way:
.menu_div ul li.active
{
background:blue;
}
and add this class to active element in your list:
<div class="menu_div">
<ul>
<li class="active"> l1c1 </li>
<li> l1c1 </li>
<li> l1c1 </li>
<li> l1c1 </li>
</ul>
</div>
.menu_div ul li#active
It says the active link needs an id of active. I see no id, hence why it is not blue.
If you want the link to be active, you are going to have to set the item to be active, the browser will not do it for you.
Just
css
.menu_div ul li.active{background:blue}
html
<div class="menu_div">
<ul>
<li id="page1"> l1c1 </li>
<li id="page2"> l1c1 </li>
<li id="page3"> l1c1 </li>
<li id="page4"> l1c1 </li>
</ul>
</div>
script
#In every page just put this script and change the id
<script>$("#page1").addClass('active');</script>

Categories

Resources