Add Active Class Based on URL of the every page - javascript

I'm trying to add an "active" class (i.e. class="active") to the appropriate menu list item based upon the page it is on once the page loads. Below is my menu(for mobile and desktop) as it stands right now. I've tried every snippet of code I could find in this regard and nothing works.
So, can someone please explain simply where and how to add in javascript to define this task?
nav ul li.active a:after {
content: '';
background: url("../img/header-active.png") no-repeat;
width: 14px;
height: 7px;
top: 24px;
right: 0px;
left: 0px;
margin: 0 auto;
position: absolute;
display: block;
}
<!-- Main menu -->
<nav class="desktop">
<ul>
<li>home</li>
<li class="active">our authors</li>
<li>our books</li>
<li>publish with us</li>
<li>careers</li>
<li>contact</li>
</ul>
</nav>
<!-- Main menu -->
<!-- Mobile menu -->
<div id="mobile-menu" class="mobile">
<div class="mob-menu" onclick="menuChange(this)">
<div class="bar1"></div>
<div class="bar2"></div>
<div class="bar3"></div>
</div>
<ul>
<li>home</li>
<li class="active">our authors</li>
<li>our books</li>
<li>publish with us</li>
<li>careers</li>
<li>contact</li>
<li>The TreeShade Bestseller Engine</li>
</ul>
</div>
<!-- Mobile menu -->

Use location.pathname.
var path = location.pathname.replace("/", "");
var anchor = document.querySelector("a[href='" + path + "']");
anchor.parentNode.classList.add("active")
I don't know why you want to do it like this, it's best to do it in the server dynamically

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!

How to use Media Queries in React?

I have this problem: I'm making header with responsive size, so when the width less than 1199px, user can see hamburger menu. To open/close menu, I'm using React Hooks and it changes display: block / none. But it has to work only when the screen is less than 1199px, but in my case it works every time, and obviously my header has display: none and there's nothing on page (there's only my logo)
Component's code:
const Header = () => {
const [navBar, showNavBar] = useState(false)
const useNavBar = () => {
showNavBar(!navBar)
}
return (
<header class="header-area main-header">
<div class="container">
<div class="row">
<div class="col-lg-2">
<div class="logo-area">
<a href='#'><img src={logo} alt="logo"/></a>
</div>
</div>
<div class="col-lg-10">
<div onClick={useNavBar} class="custom-navbar">
<span></span>
<span></span>
<span></span>
</div>
<div class="main-menu">
<ul style={navBar === true ? {display: 'block'} : {display: 'none'}}> // problem is here
<li class="active">home</li>
<li>about us</li>
<li>schedule</li>
<li>trainers</li>
<li>blog
<ul class="sub-menu">
<li>Blog Home</li>
<li>Blog Details</li>
</ul>
</li>
<li>contact</li>
<li>pages
<ul class="sub-menu">
<li>Service</li>
<li>Elements</li>
</ul>
</li>
<li class="menu-btn">
book now
</li>
</ul>
</div>
</div>
</div>
</div>
</header>
);
}
SASS code:
.main-menu
ul
float: right
#include desktop()
display: none
float: left
position: absolute
top: 60px
right: 0
z-index: 4
background: $dark
width: 40%
padding: 20px 20px 30px
PS: I don't want to add all of my CSS code, because it's over 200 strings, just explain me how to change display using media queries in my case
Don't use inline style. Change class names with JavaScript.
Set the display in your stylesheet based on the class name and media queries.
<ul className={navBar === true ? "foo" : "bar"}>

How to show/hide when hover in/out on specific element

I make a secondary menu and I like it to be displayed when user hover a specific one of the main menu items....
I tried this code but it didn't work...
.second-menu {display:none}
ul li #2:hover + .second-menu {display:block}
<ul>
<li id="1">first</li>
<li id="2">second</li>
<li id="3">third</li>
<ul>
<div class="second-menu">
<ul>
<li>page1</li>
<li>page2</li>
<li>page3</li>
</ul>
</div>
any suggestions?....
only by css or javascript....
If you wish to use CSS, you will have to put your sub menu inside the element that you want to hover.
For the CSS, C.Raf.T's answer is perfect.
If for some reason you want to use javascript you could do something like this
document.getElementById('2').addEventListener('mouseenter', function ()
{
document.getElementById('subMenu').style.display = "block";
});
document.getElementById('2').addEventListener('mouseleave', function ()
{
document.getElementById('subMenu').style.display = "none";
});
Note: the above code requires you to add a "subMenu" id to the div containing your menu. If you wish to display serval menus with only one hover event, use a class instead.
But honestly, the CSS answer is the best way to go if all you need is nested sub menus.
If the sub menu has to be outside of the parent, you will need the javascript.
.second-menu{
display:none;
}
li:hover >.second-menu{
display:block;
}
<ul>
<li id="1">first</li>
<li id="2">second
<ul class="second-menu">
<li>page1</li>
<li>page2</li>
<li>page3</li>
</ul>
</li>
<li id="3">third</li>
<ul>
Answer using Javascript,
document.getElementById('hover').onmouseover = function(){
document.getElementById('second-menu').style.display = 'block';
}
document.getElementById('hover').onmouseout = function(){
document.getElementById('second-menu').style.display = 'none';
}
.second-menu{
display:none;
}
<ul id="hover">
<li id="1">first</li>
<li id="2">second</li>
<li id="3">third</li>
<ul>
<div class="second-menu" id="second-menu">
<ul>
<li>page1</li>
<li>page2</li>
<li>page3</li>
</ul>
</div>
Here is a fiddle
By using pure CSS you have to ensure that your submenu (.second-menu) is a child-node of your hovered HTML-Element. Because CSS unfortunately doesn't know a parent selector.
By using JS you are more flexible. Means placing the submenu wherever you wish.
* { margin: 0; padding: 0; }
.second-menu {display:none; border: 1px solid blue; width: 100%; position: absolute; left: 0; right: 0; }
ul li#two:hover > .second-menu {display:block}
.relative { position: relative; border: 1px solid black; }
li { display: inline-block; }
<ul class="relative">
<li id="one">first</li>
<li id="two">second
<ul class="second-menu">
<li>page1</li>
<li>page2</li>
<li>page3</li>
</ul>
</li>
<li id="three">third</li>
<ul>

Targeting data-state to toggle nav headers

UPDATE
I discovered I could toggle the data state on click with
$(".list-header").attr("data-state", $(".list-header").hasClass('list-header') ? "hide" : "show");
However, when I click the same header I just opened, it doesn't revert back to its original icon or "hide" state.
How can I toggle the current header back to the data-state="hide" state?
$('.list-header.major').click(function(){
$(".list-header").attr("data-state", $(".list-header").hasClass('list-header') ? "hide" : "show");
$('.list-header.major').next('div').slideUp();
$(this).next('div').toggle();
$('.list-header.major').removeClass('active');
$(this).toggleClass('active');
return false;
});
===========================================================================
I need to be able to toggle the "HEADER"'s so that when the subnav is closed for any of them, the header icon is always set to a + sign, and has a data-state=hide
I found that the state of the headers is always set to active, and that the only way to toggle the + or - sign is to toggle the data-state from show to hide, which would be based on the state of the .col-wrapper classes style being either display:none or display: block.
The question is how to look for the display state of the .col-wrapper class and change the data-state based on whether the .list-header has been clicked or not. I've included screen shots of the states from the fiddle(https://jsfiddle.net/2bu35uLn/3/show/) below.
Essentially, the issue is that the icons aren't toggling back to the plus sign, if the user clicks on another header. This should force any closed list header to go back to the plus sign.
This is the closed state
This is the open state
Notice that the .col-wrapper class has display:block to show the subnav, but the .list-header class is still set to data-state="hide", which keeps the header from being toggled back to the correct state.
I'm trying to target the data-state to change to hide if the .col-wrapper class is display:none, by doing something like this:
$(".list-header").on('click', function(){
if($(this).find(".col-wrapper").css("display", "none")){
force data-state to be hide
}
});
HTML
<div class="inner">
<button data-target="#data-nav-0" data-toggle="collapse" data-state="show" class="list-header major no-style"> <span>HEADER</span> </button>
<div class="col-wrapper collapse in" id="data-nav-0" style="display: block;">
<div class="column">
<ul class="list-unstyled">
<li class="list-header mobile">link</li>
<li class="list-header desktop">head</li>
<li class="mobile chevron-right" data-target="#data-inner-0-0" data-toggle="collapse" data-state="hide">
<button class="no-style sub-header">This should toggle the ul links</button>
</li>
<ul class="inner collapse" id="data-inner-0-0">
<li>link</li>
<li>link</li>
<li>link</li>
<li>link</li>
</ul>
</ul>
</div>
<div class="column">
<ul class="list-unstyled">
<li class="list-header desktop">Link</li>
<li class="mobile chevron-right" data-target="#data-inner-0-1" data-toggle="collapse" data-state="hide">
<button class="no-style sub-header">This should toggle the ul links</button>
</li>
<ul class="inner collapse" id="data-inner-0-0">
<li>link</li>
<li>link</li>
<li>link</li>
<li>link</li>
</ul>
</ul>
</ul>
</div>
</div>
</div>
<div class="inner">
<button data-target="#data-nav-0" data-toggle="collapse" data-state="show" class="list-header major no-style"> <span>HEADER</span> </button>
<div class="col-wrapper collapse in" id="data-nav-0" style="display: block;">
<div class="column">
<ul class="list-unstyled">
<li class="list-header mobile">link</li>
<li class="list-header desktop">head</li>
<li class="mobile chevron-right" data-target="#data-inner-0-0" data-toggle="collapse" data-state="hide">
<button class="no-style sub-header">This should toggle the ul links</button>
</li>
<ul class="inner collapse" id="data-inner-0-0">
<li>link</li>
<li>link</li>
<li>link</li>
<li>link</li>
</ul>
</ul>
</div>
<div class="column">
<ul class="list-unstyled">
<li class="list-header desktop">Link</li>
<li class="mobile chevron-right" data-target="#data-inner-0-1" data-toggle="collapse" data-state="hide">
<button class="no-style sub-header">This should toggle the ul links</button>
</li>
<ul class="inner collapse" id="data-inner-0-0">
<li>link</li>
<li>link</li>
<li>link</li>
<li>link</li>
</ul>
</ul>
</ul>
</div>
</div>
</div>
jQuery
$('.list-header.major').next('div').toggle();
$('.list-header.major').click(function(){
$('.list-header.major').next('div').slideUp();
$(this).next('div').toggle();
$('.list-header').removeClass('active');
$(this).toggleClass('active');
return false;
});
$('.mobile').next('ul').toggle();
$('.mobile').click(function() {
$('.mobile').next('ul').slideUp();
$(this).next('ul').toggle();
$('.mobile button').removeClass('active');
if ($(this).next('ul').is(':visible')) {
$(this).find('button').addClass('active');
}
return false;
});
CSS
button.list-header.major {
&:before,
&:after {
color: $purple;
font-family: 'Material Icons';
font-size: 20px;
position: absolute;
right: 20px;
}
&:before {
content: "\E145"; <--THIS IS A PLUS SIGN
}
&:after {
content: "\E15B"; <--THIS IS A MINUS SIGN
}
}
.sub-header:after{
content: " >";
font-family: 'Material Icons';
display: inline-block;
transform: rotate(0);
font-size: 26px;
color: $white;
position: relative;
top: 8px;
transition: transform .3s;
}
.sub-header.active:after{
content: " v";
color: red;
display: inline-block;
transform: rotate(8deg);
font-size: 26px;
color: $neon-green;
transition: transform .3s;
}
UPDATE WITH SCREENSHOT AND MORE DETAIL
The top navigation should have a + icon, not -. Here you can see the second Header is opened and has the correct -, while the Header above it still has the -, although the contents col-wrapper has collapsed below it:
Changed code together with the author of question. Should work as expected.
$('.list-header.major').click(function(){
if (current !== this)
$(current).attr('data-state', 'hide');
$(this).attr("data-state", $(this).attr('data-state') === 'hide' ? "hide" : "show");
current = this;
$('.list-header.major').next('div').slideUp();
$(this).next('div').toggle();
$('.list-header.major').removeClass('active');
$(this).toggleClass('active');
return false;
});
Here is it the fiddle

How to add color fill effect on hover in navbar? Also how to make the end of the section or div a little slant ant a small angel?

I've used this code for my navbar :
<nav class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" href="#">Brand</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active">
Link
</li>
<li>
Link
</li>
<li class="dropdown">
Dropdown<strong class="caret"></strong>
<ul class="dropdown-menu">
<li>
Something Here
</li>
<li>
Something else here
</li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
Link
</li>
</ul>
</div>
</nav>
The above code is for simple navbar example. As I'm new to stackoverflow and have less reputation so I can't add images to my question.
Simple hover I can make using CSS but I wanted to make a hover in which if the cursor goes to any item on the navbar there is a effect like color water is filling in a glass.
Also I'm very curious about how to make the end of the section or div a little slant with some angle.
Please refer to the following link for reference:
This the template for reference
I'm trying to make a navbar and end of a section exacty like this template.
The template you refer to creates the bottom "slant" with the following CSS:
.section {
position: relative;
}
.section:after {
content: '';
display: block;
position: absolute;
right: 0;
bottom: -195px; /* the height of your image */
left: 0;
z-index: -1;
height: 195px; /* the height of your image */
background: url(path/to/your/image.png) no-repeat 50% 0%;
}

Categories

Resources