Change the active navbar color in css - javascript

I am using a simple top css navbar(just a css and html, without bootstrap/other framework) and i would like to change the active page. So when i go to the home page, the button color in navbar changes into red/whatever, likewise when i go to the other page...
here the code:
body {
margin: 0;
}
.logo {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f2f2f2;
float: left;
width: 25%;
}
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 40px;
text-decoration: none;
font-size: 18px;
}
li a:hover {
background-color: #111;
}
<ul>
<li>Home</li>
<li>News</li>
<li>Contact</li>
<li>About</li>
<li>Division</li>
<li>Career</li>
<li>MChoice's</li>
</ul>
do you have an idea? it's ok to add javascript
Thanks a lot!

What I did here is when $(document).ready(function() {..} get the path using var url = window.location.pathname; so you know which link the user coming from therefore you know which menu item they clicked.
Then $('ul li a').each(function() {...} will check each menu item, try to match the url path with the menu's href attributes, if a match found, make that menu item active (with css active class added), if not match remove the active class if any. That should do the trick.
(note: assume your app is not single page app)
for Single page app it is much easier, deactive all menu item then active the one you clicked.
$(document).ready(function() {
//var url = window.location.pathname;
var url = 'http://stacksnippets.net/js#division';
console.log('url-->', url);
$('ul li a').each(function() {
var href = $(this).attr('href');
if (!!url.match(href)) {
$(this).addClass('active');
} else {
$(this).removeClass('active');
}
});
});
body {
margin: 0;
}
.logo {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f2f2f2;
float: left;
width: 25%;
}
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 40px;
text-decoration: none;
font-size: 18px;
}
li a:hover {
background-color: #111;
}
.active {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>Home</li>
<li>News</li>
<li>Contact</li>
<li>About</li>
<li>Division</li>
<li>Career</li>
<li>MChoice's</li>
</ul>

The simplest solution would be to add an active class to the link of the page you're on:
<ul>
<li>Home</li>
<li>News</li>
<li>Contact</li>
<li>About</li>
<li>Division</li>
<li>Career</li>
<li>MChoice's</li>
</ul>
Then style those that class accordingly:
li a.active {
background: #F00;
}
If you're using a CMS (Wordpress, etc), adding some sort of active class on the active link is usually done for you. If you're doing your own static HTML, you would have to do it manually.

try below code for active menu
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('li a').on('click', function(){
$('li a').removeClass('active');
$(this).addClass('active');
});
});
</script>
<style type="text/css">
body {
margin: 0;
}
.logo {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f2f2f2;
float: left;
width: 25%;
}
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 40px;
text-decoration: none;
font-size: 18px;
}
li a:hover, li a.active {
background-color: #111;
}
</style>
<ul>
<li>Home</li>
<li>News</li>
<li>Contact</li>
<li>About</li>
<li>Division</li>
<li>Career</li>
<li>MChoice's</li>
</ul>

To change the color of active link in your navigation you need to do the following things:
On click of navigation link add css class:
$('ul li a').click(function(){
$('li a').removeClass("active");
$(this).addClass("active");
});
Add CSS for active class
ul li a.active {
background-color: #f4f4f4;
}

One possible way is to use the active selector in CSS. This selector highlights the active element you are using when its clicked.
a:active {
background-color: yellow;
}
a:focus {
background-color: yellow;
}
You can use some JQuery to turn it on and off too. Try looking at this post here, I think you may have get your answer.
(Related to How to keep :active css style after clicking an element)
jQuery('button').click(function(){
jQuery(this).toggleClass('active');
});

function redButtons() {
$(".inclusive-buttons").on("click", "a", function() {
$(".inclusive-buttons a").css("background", "#333");
$(this).css("background", "red");
})
}
var x = document.getElementsByTagName("li");
x.onclick = redButtons();
body {
margin: 0;
}
.logo {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f2f2f2;
float: left;
width: 25%;
}
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 40px;
text-decoration: none;
font-size: 18px;
}
li a:hover {
background-color: #111;
}
a:active {
background-color: red;
}
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<ul class="inclusive-buttons">
<li>Home</li>
<li>News</li>
<li>Contact</li>
<li>About</li>
<li>Division</li>
<li>Career</li>
<li>MChoice's</li>
</ul>
https://jsfiddle.net/m5gm7x7e/2/

HTML Part
<div class="navbar">
<div class="navbar-fixed-top">
<div class="container" style="width: auto;">
<div class="nav-collapse" id="nav-collapse">
<ul class="nav" id="nav">
<li id="News">News</li>
<li id="Contact">Contact</li>
<li id="About">About</li>
<li id="Division">Division</li>
<li id="Career">Career</li>
<li id="skill">Skill</li>
<li id="research">Research</li>
<li id="MChoice">MChoice's</li>
</ul>
</div>
</div>
</div>
</div>
JavaScript part
$(function() {
$('#nav li a').click(function() {
$('#nav li').removeClass();
$($(this).attr('href')).addClass('active');
});
});
CSS Part
.navbar #nav > .active > a {
color: yellow;
}
here is JSFiddle result
http://jsfiddle.net/Ag47D/775/

Here's a JSFiddle: https://jsfiddle.net/timhjellum/nw3n7eka/103/
This is a jQuery option which looks at the page URL (window.location) and specifically for a string which you define in the .indexOf(" add a unique string here ") and asks if that string is greater than -1, then locate the li element with the class you assigned to it, and add another class called active.
In the example I'm using "display" because that the URL for that iFrame that JSFiddle uses so hopefully that's not confusing.
Here's the navigation:
$(document).ready(function () {
if(window.location.href.indexOf("home") > -1) {
$(".home").addClass("active");
}
if(window.location.href.indexOf("display") > -1) {
$(".news").addClass("active");
}
//make one for each nav element
});
The HTML needs to be modified like:
<ul>
<li class="home">Home</li>
<li class="news">News</li>
<li class="contact">Contact</li>
<li class="about">About</li>
</ul>
And then a simple css addition:
li.active {
background-color: white;
}
li.active a {
color: black;
}
If you can't use jQuery, let me know but this is the easiest solution for you to implement and allow you to easily modify

You could try having separate classes in your CSS file, like "ul-home," "ul-news," etc. and define different background colors for each, then simply set the class for your <ul> tag on each page to match the class you want. So:
.ul-home {
background-color: red;
}
.ul-news {
backrgound-color: yellow;
}
And then on your home page:
<ul class="ul-home>
<li>Home</li>
<li>News</li>
</ul>
On your news page:
<ul class="ul-news">
<li>Home</li>
<li>News</li>
</ul>
Etc. with all the other pages you have.

Related

Javascript - cannot change active element

I'm completely new to JavaScript in frontend development, and I've got a really basic question I can't seem to figure out... I'm making a tabular navigation bar where the active element is highlighted.
I know there are other ways to accomplish the desired result, but what is wrong with my script here?
function navTabsClick(child) {
getElementsByClassName("active")[0].classList.remove("active");
child.getElementsByTagName("li")[0].className = "active";
}
ul{
display: flex;
list-style-type: none;
}
a{
text-decoration: none;
}
a:link, a:visited{
color: black;
}
a:hover{
cursor: pointer;
}
li{
margin: 0;
padding: 10px 30px;
background-color: lightgray;
}
li:hover{
background-color: darkgray;
}
li.active{
background-color: red;
}
<nav>
<ul>
<a onclick="navTabsClick(this)">
<li class="active">1</li>
</a>
<a onclick="navTabsClick(this)">
<li>2</li>
</a>
<a onclick="navTabsClick(this)">
<li>3</li>
</a>
</ul>
</nav>
If I remove the top line of my JavaScript function, I can get other tabs to highlight, but as is I get the following error:
Uncaught ReferenceError: getElementsByClassName is not defined
What am I missing?
Also, as a secondary question, is there a better way to handle navbar JavaScript than this?
Try doing document.getElementByClassName
function navTabsClick(child) {
document.getElementsByClassName("active")[0].classList.remove("active");
child.getElementsByTagName("li")[0].className = "active";
}
ul{
display: flex;
list-style-type: none;
}
a{
text-decoration: none;
}
a:link, a:visited{
color: black;
}
a:hover{
cursor: pointer;
}
li{
margin: 0;
padding: 10px 30px;
background-color: lightgray;
}
li:hover{
background-color: darkgray;
}
li.active{
background-color: red;
}
<nav>
<ul>
<a onclick="navTabsClick(this)">
<li class="active">1</li>
</a>
<a onclick="navTabsClick(this)">
<li>2</li>
</a>
<a onclick="navTabsClick(this)">
<li>3</li>
</a>
</ul>
</nav>
The function is document.getElementsByClassName, i.e.:
function navTabsClick(child) {
document.getElementsByClassName("active")[0].classList.remove("active");
child.getElementsByTagName("li")[0].className = "active";
}
ul {
display: flex;
list-style-type: none;
}
a {
text-decoration: none;
}
a:link,
a:visited {
color: black;
}
a:hover {
cursor: pointer;
}
li {
margin: 0;
padding: 10px 30px;
background-color: lightgray;
}
li:hover {
background-color: darkgray;
}
li.active {
background-color: red;
}
<nav>
<ul>
<a onclick="navTabsClick(this)">
<li class="active">1</li>
</a>
<a onclick="navTabsClick(this)">
<li>2</li>
</a>
<a onclick="navTabsClick(this)">
<li>3</li>
</a>
</ul>
</nav>
You are missing the document before getElementsByClassName
Others have pointed out that getElementsByClassName must be called on an element, but that does not address the second part of your question.
Is there a better way to handle navbar JavaScript than this?
Right now, you are setting an event listener on each menu item which is unnecessary. The click event exposes the element that was clicked in the target property. You can set a single event listener on the menu itself and use this property to determine which item was clicked.
This also allows you to remove the a tags around your menu items. I assume those will cause issues with screen readers. Edit: As pointed out by Scott, the click event could have been set directly on the li tag originally.
Here's a modified example with a single event for the menu.
function navClicked(nav, item) {
/* Do not attempt to set the nav
menu itself to the active item */
if (nav === item) return;
/* Do not change the active item if the
item that was clicked is already active */
if (item.classList.contains("active")) return;
/* Remove the class from all nav items */
Array.from(nav.children)
.forEach(child => child.classList.remove("active"));
/* Add the class to the item that was clicked */
item.classList.add("active");
}
ul {
display: flex;
list-style-type: none;
}
a {
text-decoration: none;
}
a:link,
a:visited {
color: black;
}
a:hover {
cursor: pointer;
}
li {
margin: 0;
padding: 10px 30px;
background-color: lightgray;
}
li:hover {
background-color: darkgray;
}
li.active {
background-color: red;
}
<nav>
<ul onclick="navClicked(this, event.target)"> <!-- 'this' is the ul element, 'event.target' is the li element that was clicked -->
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ul>
</nav>

How do I add and remove classes to multiple child elements nested in an UL with a single click using Javascript?

I want to start by apologizing for such a long question, I just hope I wont make it difficult to understand as a result.
I have created a side bar with three Menu elements in an UL which expand to show child elements, change background color and remove hover effect when clicked. I did this by defining a function that adds and remove classes containing relevant properties when the menu element is clicked.
The four specific things that I want the sidebar to do but cant seem to get it to do are as follows;
only one selected/clicked item to expand at a time while all the
rest of the unselected menu elements are collapsed. That means if I
click the first item, it expands and when I click the second one,
the first one collapses while the one I clicked expands etc.
The selected/clicked element changes its background color to
indicate it's selected.
The selected/clicked element has no hover effect on the text while
the unselected elements have a hover effect of text color change on
them.
I also want the selected menu element be able to toggle the
expansion on and off not affecting the other elements in the UL.
I think where I'm having most trouble with my code is in the adding and removal of classes especially given that the <a>Tags which are nested inside the <li> Tags (clicked elements) are where the "hover" class needs to be added/removed, as well as the <ul>Tags that expand are also nested inside the clicked elements.
function toggleMenu(e) {
var kids = document.querySelector("#menuList").children;
var unselectedLink = document.querySelectorAll(".unselected a");
var unselectedDropdown = document.querySelectorAll(".unselected ul");
//adds "unselected" class to all elements exept the selected one
for (var i = 0; i < kids.length; i++) {
kids[i].className = "unselected";
}
//adds "menuHover" class to all elements exept the selected element
for (var i = 0; i < unselectedLink.length; i++) {
unselectedLink[i].className = "menuHover";
}
for (var i = 0; i < unselectedDropdown.length; i++) {
unselectedDropdown[i].classList.remove("show")
}
//adds "selected" class, removes "menuHover" class and adds "toggle" to the selected element
e.className = "selected";
document.querySelector(".selected a").classList.remove("menuHover");
document.querySelector(".selected ul").classList.toggle("show");
}
.sidebar {
position: fixed;
width: 250px;
height: 100%;
left: 0px;
top: 0;
background: #1b1b1b;
font-family: sans-serif;
}
.menu-bar {
background: #1b1b1b;
height: 60px;
display: flex;
align-items: center;
padding-left: 42px;
}
.side-text {
color: #C5C5C5;
font-weight: bold;
font-size: 20px;
}
nav ul {
background: #1b1b1b;
height: 100%;
width: 100%;
list-style: none;
margin-left: 0;
padding-left: 0;
}
nav ul li {
line-height: 40px;
}
nav ul li a {
position: relative;
color: #C5C5C5;
text-decoration: none;
font-size: 14px;
padding-left: 43px;
font-weight: normal;
display: block;
width: 100%;
}
nav ul ul {
position: static;
display: none;
}
nav ul ul li a {
font-family: sans-serif;
font-size: 13px;
color: #e6e6e6;
padding-left: 80px;
font-weight: lighter;
}
.submenu-item:hover {
background: #1e1e1e!important;
}
/*...........selected and show..................*/
.selected {
background-color: #255DAA;
}
.show {
display: block;
}
/*...........unselected and hover..................*/
.unselected {
color: #1e1e1e;
}
.menuHover:hover {
color: #255DAA;
}
<nav class="sidebar">
<div class="menu-bar">
<label class="side-text">MENU</label>
</div>
<ul id="menuList">
<li class="selected" onclick="toggleMenu(this)">
Staff
<ul>
<li>New Staff</li>
<li>View Staff</li>
</ul>
</li>
<li class="unselected" onclick="toggleMenu(this)">
Notes
<ul>
<li>New Note</li>
<li>Edit Notes</li>
</ul>
</li>
<li class="unselected" onclick="toggleMenu(this)">
Tasks
<ul>
<li>New Tasks</li>
<li>Edit Task</li>
</ul>
</li>
</nav>
I am quite close but somehow, logically I am doing things the wrong way with the JavaScript, so any adjustments to the code to make it reach all four of the above goals will be much appreciated. thanks
A simple way to do this:
If the element was selected, just unselect it
If it wasnt, unselect all elements and select the clicked element
function toggleMenu(el) {
if (el.classList.contains("selected")) {
el.classList.remove("selected");
el.classList.add("unselected");
}
else {
for (const child of document.getElementById("menuList").children) {
child.classList.remove("selected");
child.classList.add("unselected");
}
el.classList.remove("unselected");
el.classList.add("selected");
}
}
Edit 1
You can use the following css to unhide the submenu of a selected menuitem:
.selected ul {
display: block;
}
Edit 2
I went to the trouble of actually implementing it.
function toggleMenu(el) {
if (el.classList.contains("selected")) {
el.classList.remove("selected");
el.classList.add("unselected");
}
else {
for (const child of document.getElementById("menuList").children) {
child.classList.remove("selected");
child.classList.add("unselected");
}
el.classList.remove("unselected");
el.classList.add("selected");
}
}
.sidebar {
position: fixed;
width: 250px;
height: 100%;
left: 0px;
top: 0;
background: #1b1b1b;
font-family: sans-serif;
}
.menu-bar {
background: #1b1b1b;
height: 60px;
display: flex;
align-items: center;
padding-left: 42px;
}
.side-text {
color: #C5C5C5;
font-weight: bold;
font-size: 20px;
}
/* menu */
.menu {
background: #1b1b1b;
height: 100%;
width: 100%;
list-style: none;
margin-left: 0;
padding-left: 0;
}
.menu-item {
line-height: 40px;
}
.menu-item a {
position: relative;
color: #C5C5C5;
text-decoration: none;
font-size: 14px;
padding-left: 43px;
font-weight: normal;
display: block;
width: 100%;
}
/* submenu */
.submenu {
position: static;
display: none;
list-style: none;
}
.submenu-item a {
font-family: sans-serif;
font-size: 13px;
color: #e6e6e6;
padding-left: 80px;
font-weight: lighter;
}
.submenu-item:hover {
background: #1e1e1e;
}
/* selected and unselected */
.selected {
background-color: #255DAA;
}
.selected .submenu {
display: block;
}
.unselected {
color: #1e1e1e;
}
.unselected:hover a {
color: #255DAA;
}
<nav class="sidebar">
<div class="menu-bar">
<label class="side-text">MENU</label>
</div>
<ul class="menu" id="menuList">
<li class="menu-item selected" onclick="toggleMenu(this)">
Staff
<ul class="submenu">
<li class="submenu-item">New Staff</li>
<li class="submenu-item">View Staff</li>
</ul>
</li>
<li class="menu-item unselected" onclick="toggleMenu(this)">
Notes
<ul class="submenu">
<li class="submenu-item">New Note</li>
<li class="submenu-item">Edit Notes</li>
</ul>
</li>
<li class="menu-item unselected" onclick="toggleMenu(this)">
Tasks
<ul class="submenu">
<li class="submenu-item">New Tasks</li>
<li class="submenu-item">Edit Task</li>
</ul>
</li>
</ul>
</nav>
As alternative to the accepted answer, here two different approaches I was working on...
#menuList li is a container for a list of <a> menu items which have adjacent <ul> sub-menu-items. For easy selection with CSS I assigned class .menu-item to those <a>.
The CSS logic for both versions is essentially equal:
set the .menu-item adjacent ul sub-menu-items hidden by default
define :hover colors
define colors for a selected .menu-item and adjacent ul (either :focus or .selected is true)
make .menu-item adjacent ul sub-menu-items visible when a .menu-item gets selected (ditto)
Difference: for CSS only we use the :focus selector, for CSS with Javascript we use class .selected.
CSS only (automatic focus and blur)
An <a> gets focus when clicked (like button, input, etc. :focus is true). When the user clicks/taps outside the focussed element it automatically loses focus again (gets blurred and :focus is false, as in :not(:focus) = 'blur'). We can use the CSS :focus selector to handle user clicks and modify elements, MDN: ':focus'.
CSS with Javascript (focus and blur on request)
The OP wants a selected .menu-item and its adjacent ul sub-menu-items to stay visible until the user specifically deselects it again. This cannot be done with the :focus selector, so we ignore that selector and use class .selected instead to handle focus and blur requirements ourselves, MDN: HTMLElement.blur().
The Javascript logic is fairly straightforward:
Attach a 'click'-eventListener (MDN: Element: click event) to main container #menuList handling:
when a .menu-item gets selected and it is the currently .selected then blur it (menuItemBlur())
otherwise
when we have a previously selected .menu-item open, blur that first (menuItemBlur())
and then focus the newly selected .menu-item (menuItemFocus())
Changes to OP code
removed unneeded CSS
removed unneeded class attributes from HTML
changed href="#" in <#menuList li a> to href="javascript:void(0)" to prevent it from creating an entry in the browser history (sub-menu-items will still create an entry).
The below snippet is heavily commented and should be self-explanatory.
'use-strict';
var activeItem; // Holds the currently '.selected''.submenu' (null/undefined if none)
// Attach 'click' event listener to the #menuList
document.getElementById('menuList')
.addEventListener('click', function(e) { menuItemToggle(e.target) });
function menuItemToggle(el) {
if (el.classList.contains('menu-item2')) { // When a '.menu-item' gets clicked (not its kids)
if (el.classList.contains('selected')) { // and it is the '.selected''.menu-item'
menuItemBlur(el); // then close it and remove focus()
}
else {
if (activeItem) // When there is a currently selected '.menu-item'
menuItemBlur(activeItem); // then deactivate it
menuItemFocus(el); // Now activate the clicked `.menu-item`
};
};
function menuItemBlur(el) {
el.classList.remove("selected"); // Set the '.menu-item' to not '.selected'
activeItem = null; // and remove the reference to it
el.blur(); // Remove focus from element for CSS ':focus'
// ...extend with other 'Blur' stuff...
};
function menuItemFocus(el) {
el.classList.add("selected"); // Set the '.menu-item' to '.selected'
activeItem = el; // and save a reference to it
// ...extend with other 'Focus' stuff...
};
};
.sidebar {
position: fixed;
width: 250px;
height: 100%;
left: 0px;
top: 0;
background: #1b1b1b;
font-family: sans-serif;
}
.menu-bar {
background: #1b1b1b;
height: 60px;
display: flex;
align-items: center;
padding-left: 42px;
}
.side-text {
color: #c5c5c5;
font-weight: bold;
font-size: 20px;
}
nav ul {
background: #1b1b1b;
height: 100%;
width: 100%;
list-style: none;
margin-left: 0;
padding-left: 0;
}
nav ul li {
line-height: 40px;
}
nav ul li a {
position: relative;
color: #c5c5c5;
text-decoration: none;
font-size: 14px;
padding-left: 43px;
font-weight: normal;
display: block;
width: 100%;
}
nav ul ul {
position: static;
display: none;
}
nav ul ul li a {
font-family: sans-serif;
font-size: 13px;
color: #e6e6e6;
padding-left: 80px;
font-weight: lighter;
}
/*************/
/* ADDED CSS */
/*************/
/* All classes starting with "menu-item" */
[class^="menu-item"] + ul { display: none } /* hide adjacent UL */
[class^="menu-item"]:hover { color: #255daa } /* hover color */
a + ul li a:hover { color: #c5c5c5; background-color: #1b1b1b }
/*
menu-item adjacent sub-menu-items hover colors
Here the generic form is used, but it would
probably be more clear to be specific and use:
- either .menu-item1:focus + ul li a:hover
- or .menu-item2.selected + ul li a:hover
*/
/*
':focus' version
This version uses the CSS ':focus' without any Javascript.
Main difference with the '.selected' version below is that when the
user clicks outside the '.menu-item', the '.menu-item' looses focus
and therefore gets hidden again (as :focus is no longer true).
*/
.menu-item1:focus,
.menu-item1:focus + ul { color: #e6e6e6; background-color: #255DAA } /* focus colors */
.menu-item1:focus + ul { display: block } /* show adjacent UL */
/*
'.selected' version, with Javascript.
Basically the same CSS, but now using class '.selected' instead of ':focus'.
Closing occurs only on user specific 'click'.
*/
.menu-item2.selected,
.menu-item2.selected + ul { color: #e6e6e6; background-color: #255DAA } /* focus colors */
.menu-item2.selected + ul { display: block } /* show adjacent UL */
/*********************/
/* for demo use only */
/*********************/
nav h3 {
color: rgba(100, 149, 237,.9); /* CornflowerBlue */
font-style: italic;
padding-left: 43px;
}
.anchor {
color: white;
padding-left: 43px;
}
.content {
font-size: 1.5rem;
margin: 5rem 300px;
}
/* preferred globals */
html,body { box-sizing: border-box; width: 100%; max-width: 100% }
*::before,*::after, * { box-sizing: inherit }
body { margin: 0 }
<nav class="sidebar">
<div class="menu-bar">
<label class="side-text">MENU</label>
</div>
<h3>test</h3>
<a class="anchor" href="javascript:void(0)">some '.sidebar' <a></a>
<ul id="menuList">
<h3>:focus version</h3>
<li>
<a class="menu-item1" href="javascript:void(0)">Staff</a>
<ul>
<li>New Staff</li>
<li>View Staff</li>
</ul>
</li>
<li>
<a class="menu-item1" href="javascript:void(0)">Notes</a>
<ul>
<li>New Note</li>
<li>Edit Notes</li>
</ul>
</li>
<li>
<a class="menu-item1" href="javascript:void(0)">Tasks</a>
<ul>
<li>New Tasks</li>
<li>Edit Task</li>
</ul>
</li>
<h3>.selected version</h3>
<li>
<a class="menu-item2" href="javascript:void(0)">Staff</a>
<ul>
<li>New Staff</li>
<li>View Staff</li>
</ul>
</li>
<li>
<a class="menu-item2" href="javascript:void(0)">Notes</a>
<ul>
<li>New Note</li>
<li>Edit Notes</li>
</ul>
</li>
<li>
<a class="menu-item2" href="javascript:void(0)">Tasks</a>
<ul>
<li>New Tasks</li>
<li>Edit Task</li>
</ul>
</li>
</ul>
</nav>
<div class="content">
<h3><b>Note</b></h3>
<p>
This demo uses two different approaches interchangeably creating a quirky behaviour,
which under normal circumstances would not exist.
</p>
<p>To reproduce:</p>
<ul>
<li>select a <i>':focus version'</i> menu item first
<li>then select a <i>'.selected version'</i> menu item
</ul>
<p>
As you can see, the selected <i>':focus version'</i> loses focus and a second
'click' is needed to activate the <i>'.selected version'</i> menu item.
This is because the first click event of the <i>'.selected version'</i> gets consumed by the blur event
of the <i>':focus version'</i>.
</p>
<p>Just so you know...</p>
</div>

issue with jquery smooth scroll spy not working in mobile view

I have menus bars in website this is a single page website. When user click on a memu scrollspy event gets activated through jquery. Till Here it is working well but when i switch to mobile view their is not smooth scrollspy effect.
I HAVE WRITTEN WITH CUSTOM CSS
Here is the HTML CODE
<div class="col-md-9 col-sm-9 nav-wrapper" id="myNavbar">
<!-- Nav Start -->
<nav class="navbar1">
<ul class="sf-menu" id="menu">
<li>Home</li>
<li>About Us</li>
<li>Practice Areas</li>
<li>Clients</li>
<li>Team</li>
<li>Careers</li>
<li>Contact</li>
</ul>
</nav>
<!-- Nav End -->
</div>
Here is the Jquery Script
<script>
$('body').scrollspy({target: ".navbar1", offset: 50});
$("#myNavbar a").on('click', function(event){
if(this.hash != ""){
event.preventDefault();
}
//store hash
var hash = this.hash;
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 500, function(){
window.location.hash = hash;
});
});
});
</script>
HERE IS THE CSS CODE
THE CSS CODE IS VERY LONG SO I HAVE FILTERED HERE
header .nav-wrapper {
float: right;
}
header .nav-wrapper ul {
float: right;
}
.sf-menu .menu-description {
display: none;
}
sf-menu li a {
padding: 10px 18px;
}
.sf-menu li li a {
padding-top: 3px;
padding-bottom: 3px;
}
.sf-menu > li {
margin-top: 10px;
}
.sf-menu > li {
margin-top: 0;
height: 60px;
line-height: 40px;
}
.sf-menu {
margin-bottom: 0;
}
.sf-menu ul {
box-shadow: none;
border-top: 0;
}
.sf-menu a {
padding-top: 0;
padding-bottom: 0;
font-weight: normal;
}
.sf-menu li {
text-transform: none;
background: none;
}
Here is the desktop view
Here is the mobile View
THANKS IN ADVANCE

Nav bar mouseenter/mouseleave not working between li elements

I'mm trying to design a specific type of navbar in javascript/jquery.
I cannot get mouseenter() and mouseleave() to work correctly when the mouse passes between the li objects.
Here is my code. Any ideas?
http://jsfiddle.net/richofwombwell/1v8L0pdz/38/
function inversebuttonon(liId, aId) {
$(liId).css('background-color', 'white');
$(aId).css('background-color', 'white');
$(aId).css('color', '#0086CA');
}
function inversebuttonoff(liId, aId) {
$(liId).css('background-color', '#0086CA');
$(aId).css('background-color', '#0086CA');
$(aId).css('color', 'white');
}
function showselectedmenu(liclass, aclass) {
$('.menu').css('max-height', '100px');
$(liclass).css('display', 'inline');
$(aclass).css('display', 'inline');
}
function dontshowselectedmenu(liclass, aclass) {
$('.menu').css('max-height', '0px', 'none');
$(liclass).css('display', 'none');
$(aclass).css('display', 'none');
}
$('#n-2').mouseenter(function () {
inversebuttonon('#n-2', '#a2');
showselectedmenu('.tmenuli', '.tmenua1');
});
$('.menu').mouseleave(function () {
dontshowselectedmenu('.tmenuli', '.tmenua1');
inversebuttonoff('#n-2', '#a2');
});
$('#n-3').mouseenter(function () {
inversebuttonon('#n-3', '#a3');
showselectedmenu('.tmenuli2', '.tmenua2');
});
$('.menu').mouseleave(function () {
dontshowselectedmenu('.tmenuli2', '.tmenua2');
inversebuttonoff('#n-3', '#a3');
});
Your script does not work correctly because your html code is invalid (you are nesting DIVs instead of list elements. That forces the browser to correct your code (the way it wants to).
Before you continue scripting, please consider using CSS solution:
* {
box-sizing: border-box;
font-family: sans-serif;
font-size: 16px;
}
.my_menu {
height: 66px;
text-align: center;
width: 100%;
overflow:
}
.my_menu ul {
list-style: none;
}
.my_menu ul li {
display: inline-block;
}
.my_menu > ul {
position: relative;
background: none #0086CA;
}
.my_menu ul a {
text-decoration: none;
color: #fff;
display: inline-block;
}
.my_menu > ul > li > a {
padding: 15px 20px;
}
.my_menu > ul > li > a:hover,
.my_menu > ul > li a:focus {
color: #0086CA;
background: #fff;
}
.my_menu ul ul {
background: none grey;
position: absolute;
top: 100%;
left: 0;
right: 0;
width: 100%;
display: none;
}
.my_menu ul li:hover ul {
display: block;
}
.my_menu ul ul a {
padding: 5px 10px;
}
.my_menu ul ul a:hover,
.my_menu ul ul a:focus {
background: none black;
}
<header>
<nav class="my_menu">
<ul>
<li>
Home
</li>
<li>
menuitem1
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
</ul>
</li>
<li>
menuitem2
<ul>
<li>item5</li>
<li>item6</li>
<li>item7</li>
<li>item8</li>
</ul>
</li>
</ul>
</nav>
</header>
Also at Playground.
You can probably clean this up but if you insist on a script method, this will work: It also should be easier to extend with less id's etc. just add markup.
Working example here: http://jsfiddle.net/MarkSchultheiss/fLqs1nru/2/
function showmenu(targ, me) {
$('.menuitem').removeClass('menu-on');
$(me).parent().addClass('menu-on');
$('.menu').hide();
$('.' + targ).show();
}
$('.menuitem a').mouseenter(function () {
var targ = $(this).parent().data("targetmenu");
showmenu(targ, this);
});
$('nav').mouseleave(function () {
$('.menuitem ').removeClass('menu-on');
$('.menu').hide();
});
Adjust the markup, get rid of the div and add some classes. Add a data element for the target menu to use.
<nav>
<ul class="ulparent">
<li class="navitem" id="n-1">Home
<li class="navitem menuitem" data-targetmenu="menu1">menuitem1
</li>
<li class="navitem menuitem" data-targetmenu="menu2"><a href="#" >menuitem2</a>
</li>
<ul class="menu menu1">
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
</ul>
<ul class="menu menu2">
<li>item5</li>
<li>item6</li>
<li>item7</li>
<li>item8</li>
</ul>
</ul>
</nav>
add this to the end of you CSS (which can probably be cleaner but this is only additive:)
.menu-on {
background-color: white;
}
.menu-on a {
color:#0086CA;
}
.menu {
max-height:100px;
display:none;
}

stopping dropdown navigation bar from pushing elements aside

I have a dropdown navigation bar, and when elements like buttons or images are too high up on the page, the navigation bar pushes the elements to the right side when drop-down options appear. How do I stop this?
Navbar:
<nav id="nav1">
<ul>
<li>Home</li>
<li onmouseover = "DropDown1()" onmouseout="DropUp1()">Images<ul class="DropUp" id="Droplist1" >
<li class="DropDown"><a id="Droplist1" href="#">Test1</a></li>
<li class="DropDown">Test2</li>
<li class="DropDown">Test3</li></ul>
</li>
<li onmouseover = "DropDown2()" onmouseout="DropUp2()">Adverts<ul id="Droplist2" class="DropUp">
<li class="DropDown">Test1</li>
<li class="DropDown">Test2</li></ul>
</li>
<li>Data Validation</li>
<li>Security</li>
</ul>
</nav>
CSS:
nav#nav1 li a {
display: block;
padding: 3px 8px;
background-color: #5e8ce9;
color: #fff;
text-decoration: none;
}
nav#nav1 li {
list-style: none;
float: left;}
.DrowDown {
display: block;
position: absolute;
margin: 0;
padding: 0;
float: none;
}
nav#nav1 li:hover li {
float: none; }
nav#nav1 li:hover li a {
background-color: #69f;
border-bottom: 1px solid #fff;
color: #000; }
#navbar li li a:hover {
background-color: #8db3ff; }
nav#nav1 ul li a:hover { background: #686868 ; }
nav#nav1 ul li a:active { background: #F0F0F0; }
JavaScript functions for dropdown:
function DropDown2() {
var t = document.getElementById("Droplist2");
t.className = "DropDown";
}
function DropDown1() {
var t = document.getElementById("Droplist1");
t.className = "DropDown";
}
function DropUp2() {
var t = document.getElementById("Droplist2");
t.className = "DropUp";
}
function DropUp1() {
var t = document.getElementById("Droplist1");
t.className = "DropUp";
}
If you are wondering why I took such a difficult route for making the navigation bar, it's because I have to use JavaScript.
Here is JS fiddle example: http://jsfiddle.net/fNPvf/10015/
The window is small in the fiddle, and the effect is slightly different, but notice how when you hover over "Data Validation" the dropdown menu pushes the text/image/body downwards?
You need absolute positioning and a higher z-index for either the containing <div> or the <ul> itself. Just add this to your code and adjust the z-index as needed:
nav#nav1 ul{
position: absolute;
top: 0;
z-index: 9;
}
See working demo here

Categories