responsive horizontal menu with dropdown menus - javascript

I have a horizontal responsive menu that works great, here is link to the page with it
I tried to make a new one with dropdown menus but can't get it to work. Instead of having a dropdown appear on hover, it shows the menus automatically in the line below. Here is link to codepen showing the errors http://codepen.io/mlegg10/pen/akLaVA
$(document).ready(function() {
$('nav').prepend('<div id="responsive-nav" style="display:none">Menu</div>');
$('#responsive-nav').on('click', function() {
$('nav ul').slideToggle()
});
$(window).resize(function() {
if ($(window).innerWidth() < 768) {
$('nav ul li').css('display', 'block');
$('nav ul').hide()
$('#responsive-nav').show()
} else {
$('nav ul li').css('display', 'inline-block');
$('nav ul').show()
$('#responsive-nav').hide()
}
});
$(window).resize();
});
$(document).on('scroll', function() {
if ($(document).scrollTop() > 100) {
$('#nav').addClass('fixed')
} else {
$('#nav').removeClass('fixed')
}
});
body {
margin: 0;
font-family: Georgia;
}
#menu-bar {
width: 100%;
height: auto;
margin: 50px auto 0;
background-color: #ff4500;
text-align: center;
}
#header h1 {
padding: 15px 0;
margin: 0;
}
#nav {
background-color: #036;
text-align: center;
}
#nav ul {
list-style: none;
padding: 0;
margin: 0
}
#nav ul li {
display: inline-block;
padding: 5px 0;
margin: 0;
}
#nav.fixed {
width: 100%;
position: fixed;
top: 0;
left: 0;
}
nav ul li a {
padding: 0 5px;
text-decoration: none;
color: #fff;
}
nav ul li:hover {
background-color: #ff0000;
}
#responsive-nav {
cursor: pointer;
color: #fff;
font-family: Georgia;
font-weight: bold;
padding: 5px 0;
}
#content {
width: 90%;
margin: 0 auto 20px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
border: 1px solid #ddd;
padding: 5px;
}
#drop-nav li ul li {
border-top: 0px;
#drop-nav li ul li {
border-top: 0px;
}
ul li a {
display: block;
background: #036;
padding: 5px 10px 5px 10px;
text-decoration: none;
white-space: nowrap;
color: #fff;
}
ul li a:hover {
background: #f00;
}
**this part is in the head tags:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://responsive-nav.com/demo/responsive-nav.js"></script>**
<header id="menu-bar">
<nav id="nav">
<ul>
<li>Home
</li>
<li>Accomodations
</li>
<li>Amenities
</li>
<li>Rates
</li>
<li>Links
<ul>
<li>Dropwdown 1
</li>
<li>Dropdown 2
</li>
</ul>
</li>
<li>Contact
</li>
</ul>
</nav>
</header>

Your javascript code has lots of unclosed line endings - you are missing the semicolons quiet often.
Additionally, jQuery will apply nav ul to all elements it finds. Meaning if there is a second occurrence, which is the case in your case, it will be applied to that too.
Instead: you should give your level 0 menu a clean, identifiable class, which you can preciesly target:
<!-- Your new HTML Markup -->
<nav class="mother-of-all-dropdown-lists">
and then in your jQuery:
$('.mother-of-all-dropdown-lists').slideToggle();
Sorry, that I keep writing, there are jQuery selectors wrong as well:
The id / hashtag is missing, so..:
$('nav ul li').css('display','inline-block');
$('nav ul').show()
should be:
$('#nav ul li').css('display','inline-block');
$('#nav ul').show();

Related

Menu item doesn't open

I have found a simple dropdown menu which works fine by me, but only the subitem links open.
When i click 'Home' nothing happens (it should open google page), when i click 'info2' google will open.
I think it has something to do with de .js file but i just dont see it.
Hope someone can help me out with a simple trick.
$(document).ready(function(){
$("#nav > li > a").on("click", function(e){
if($(this).parent().has("ul")) {
e.preventDefault();
}
if(!$(this).hasClass("open")) {
// hide any open menus and remove all other classes
$("#nav li ul").slideUp(350);
$("#nav li a").removeClass("open");
// open our new menu and add the open class
$(this).next("ul").slideDown(350);
$(this).addClass("open");
}
else if($(this).hasClass("open")) {
$(this).removeClass("open");
$(this).next("ul").slideUp(350);
}
});
});
ul, li, td {
padding: 0;
border: 0;
vertical-align: baseline;
outline: none;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
ol, ul { list-style: none; }
table { border-collapse: collapse; border-spacing: 0; }
/* nav menu styles */
#nav {
display: block;
width: 280px;
margin: 0 auto;
}
#nav li {font-size:19px; text-align:center;}
#nav > li > a {
display: block;
padding: 16px 18px;
color: #fff;
text-decoration: none;
border-bottom: 1px solid #212121;
background-color: #0069b3;
}
#nav > li > a:hover, #nav > li > a.open {
color: #fff;
border-bottom-color: #384f76;
background-color: #083562;
}
#nav li ul { display: none; background: #083562; }
#nav li ul li a {
display: block;
background: none;
padding: 10px 0px;
text-decoration: none;
color: #fff;
}
#nav li ul li a:hover {
background: #014f86;
}
<!doctype html>
<html lang="en-US">
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
</head>
<body>
<div id="w">
<nav>
<ul id="nav">
<li>Home</li>
<li>Info
<ul>
<li>info2</li>
<li>info3</li>
</ul>
</li>
</nav>
</div>
</body>
</html>
It looks like .has() method can't be use in this way because not return boolean, but jQuery object. Change this:
if($(this).parent().has("ul")) {
e.preventDefault();
}
To this and let me know if it helps you:
if($(this).parent().has("ul").length === 1) {
e.preventDefault();
}

How to change + to - when parent menu is clicked [duplicate]

This question already has answers here:
Selecting and manipulating CSS pseudo-elements such as ::before and ::after using javascript (or jQuery)
(26 answers)
Closed 3 years ago.
How to change + to - when menu parent menu item is clicked. i was looking to target ::after element using jquery but i cant find way to target pseudo element using jquery
I want to change below css to when perent menu is clicked
.ir-nav-w > ul li::after {
/* padding-left: 10px; */
text-transform: uppercase;
content: "-";
position: absolute;
left: 15px;
top: 4px;
line-height: 30px;
font-size: 20px;
z-index: 0;
}
Fiddle code
$(".nav-w > ul > li > a").click(function() {
$(this).next().slideToggle();
});
//open active list
$('.nav-w ul li').children().has('.active-menu').css('display', 'block');
// compare url with nav url to show active url
$(function() {
//var url = window.location.href;
var url = window.location.pathname;
var pgurl = window.location.href.substr(
window.location.href.lastIndexOf("/") + 1
);
$(".nav-w ul li a").each(function() {
if ($(this).attr("href") == url || $(this).attr("href") == "") {
$(this).addClass("active-menu");
}
});
console.log("url : " + window.location.pathname);
});
.nav-w a {
color: black;
padding: 10px 15px;
padding-left: 35px;
text-decoration: none;
display: block;
border-bottom: 1px solid #f1f1f1;
font-size: 12px;
font-weight: 600;
/* color: #178B43 !important; */
color: #757575;
}
/* ul inside content area*/
.nav-w ul {
margin-left: 0px;
list-style-type: none;
margin-bottom: 0px;
}
.nav-w ul li {
/*padding-left: 10px;*/
text-transform: uppercase;
position: relative;
width: 100%;
}
/* ol inside content area*/
.nav-w>ul {
padding-left: 0px;
padding-right: 0px;
}
.nav-w ul>li ul {
padding-left: 0px;
padding-right: 0px;
display: none;
}
.active-menu {
color: red !important;
}
.nav-w>ul li::after {
text-transform: uppercase;
content: "+";
position: absolute;
left: 15px;
top: 4px;
line-height: 30px;
font-size: 20px;
z-index: 0;
}
.nav-w>ul li ul li::after {
text-transform: uppercase;
content: "";
position: absolute;
left: 0px;
top: 5px;
line-height: 32px;
font-size: 20px;
z-index: 0;
}
.nav-w ul li ul li a {
padding-left: 45px;
}
.nav-w a:hover {
background: #f5f5f5;
border-left: 2px solid #178B43;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="nav-w">
<ul class="">
<li>Share Information
<ul class="" style="display: none;">
<li>Share Overview</li>
<li>Share Graph </li>
<li>Investement Calculator</li>
<li>Historical Share Prices</li>
</ul>
</li>
<li>Financial Information
<ul class="" style="display: none;">
<li>Earning Releases</li>
<li>Financial Statements</li>
<li><a href="/investor-relations/financial-information/presentation">Presentation
</a></li>
<li><a href="/investor-relations/financial-information/quarterly-key-figures">Quarterly Key Figures
</a></li>
<li><a href="/investor-relations/financial-information/annual-key-figures">Annual Key Figures
</a></li>
</ul>
</li>
</ul>
</div>
The way I would do it is to add a class to the parent menu after it is clicked, such as open.
And then in your css you could add a special modifier:
.nav-w > ul li.open::after {
content: "-"
}
And when it is click again, remove the class open.
You can't manipulate :after, because it's not technically part of the DOM and therefore is inaccessible by any JavaScript. But you can add a new class with a new ::after specified.
Add this to your code:
// JS
const $listItems = $('.ir-nav-w > ul li');
$listItems.onClick(
$listItems.removeClass('closed');
this.addClass('closed')
);
// CSS
.ir-nav-w > ul li.closed::after {
content: "+";
}
Trick is to add css:
.nav-w > ul li.selected::after {
content: "-";
}
and toggle selected class on click:
$(".nav-w > ul > li > a").click(function () {
$(this).parent().toggleClass("selected");
$(this).next().slideToggle();
});
$(".nav-w > ul > li > a").click(function () {
$(this).parent().toggleClass("selected");
$(this).next().slideToggle();
});
//open active list
$('.nav-w ul li').children().has('.active-menu').css('display', 'block');
.nav-w a {
color: black;
padding: 10px 15px;
padding-left: 35px;
text-decoration: none;
display: block;
border-bottom: 1px solid #f1f1f1;
font-size: 12px;
font-weight: 600;
/* color: #178B43 !important; */
color: #757575;
}
/* ul inside content area*/
.nav-w ul{
margin-left: 0px;
list-style-type:none;
margin-bottom:0px;
}
.nav-w ul li{
/*padding-left: 10px;*/
text-transform:uppercase;
position:relative;
width:100%;
}
/* ol inside content area*/
.nav-w > ul {
padding-left: 0px;
padding-right: 0px;
}
.nav-w ul > li ul {
padding-left: 0px;
padding-right: 0px;
display:none;
}
.active-menu {
color: red !important;
}
.nav-w > ul li::after {
text-transform: uppercase;
content: "+";
position: absolute;
left: 15px;
top: 4px;
line-height: 30px;
font-size: 20px;
z-index: 0;
}
.nav-w > ul li.selected::after {
content: "-";
}
.nav-w > ul li ul li::after {
text-transform: uppercase;
content: "";
position: absolute;
left: 0px;
top: 5px;
line-height: 32px;
font-size: 20px;
z-index: 0;
}
.nav-w ul li ul li a {
padding-left:45px;
}
.nav-w a:hover {
background: #f5f5f5;
border-left: 2px solid #178B43;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="nav-w">
<ul class="">
<li>Share Information
<ul class="" style="display: none;">
<li>Share Overview</li>
<li>Share Graph </li>
<li><a href="/investor-relations/share-nformations/investor-calculator/" >Investement Calculator</a></li>
<li>Historical Share Prices</li>
</ul>
</li>
<li>Financial Information
<ul class="" style="display: none;">
<li>Earning Releases</li>
<li>Financial Statements</li>
<li><a href="/investor-relations/financial-information/presentation">Presentation
</a></li>
<li><a href="/investor-relations/financial-information/quarterly-key-figures">Quarterly Key Figures
</a></li>
<li><a href="/investor-relations/financial-information/annual-key-figures">Annual Key Figures
</a></li>
</ul>
</li>
</ul>
</div>
It's not actually possible to target :after, because it isn't part of the DOM and can't be accessed through JavaScript code. This isn't a jQuery limitation.
You could just set a class on the element itself, and change the :after rule when the class is set, i.e.:
.nav-w > ul li.active::after
{
content: "-"
}
Add active class to the anchors' parent:
$(".nav-w > ul > li a").click(function () {
$(this).next().slideToggle();
$(this).parent().toggleClass('active');
});
And replace ::after on the active class:
.nav-w > ul li.active::after {
content: '-'
}
You can do with :after prop.
You can do something like this
.li-item::after{
content: "+";
}
.li-item-minus::after{
content: "-" !important;
}
While in jQuery - you can toggle class .li-item-minus on click of each list item
jQuery(".naw-v ul li").on("click", function(){
jQuery(this).toggleClass("li-item-minus");
});
Which means - on click of this li element, you toggleClass li-item-minus which has different content form main one.

Why are the anchors in my submenu returning false?

I am writing a jquery dropdown script for my navigation submenus. I have return false on the top level anchors but the problem is that this is also applying to the anchors in the submenus. My script also adds chevrons to the top level links that have submenus but those are also being added to the submenu links. What am I doing wrong? Here is a jsFiddle. Thanks for your time.
<div class="nav-outter">
<nav>
<ul>
<li>Home</li>
<li class="has-submenu">Services
<ul>
<li>Web Development</li>
<li>Photography</li>
<li>Multimedia</li>
</ul>
</li>
</ul>
</nav>
</div>
$(document).ready(function() {
$('nav > ul > li.has-submenu').each(function() {
$(this).find('a:first-child').each(function() {
$(this).append('<i class="fa fa-chevron-down"></i>');
$(this).on('click', function(e) {
e.preventDefault();
$(this).parent().find('ul').each(function() {
if ($(this).hasClass('active')) {
$(this).removeClass('active')
.slideUp(300);
} else {
$(this).addClass('active')
.slideDown(300);
}
});
});
});
});
});
.nav-outter {
position: relative;
z-index: 1;
}
nav > ul {
list-style: none;
}
nav > ul > li {
display: inline-block;
}
nav > ul > li > a {
padding: 3px 15px;
font-size: 1.2em;
color: #2c3e50;
text-decoration: none;
}
nav > ul > li > ul {
display: none;
position: absolute;
z-index: 5;
list-style: none;
border: 1px solid #FC4349;
border-bottom: 0px;
margin-left: 0px;
padding-left: 0px;
margin-top: 3%;
}
nav > ul > li > ul > li {
border-bottom: 1px solid #FC4349;
}
nav > ul > li > ul > li > a {
display: block;
padding: 15px 25px 15px 10px;
text-align: left;
background: #fff;
color: #FC4349;
text-decoration: none;
}
The find('a:first-child') is going to include every first child which is all of the links since each one is a first-child
A simpler approach would be just target the children of has-submenu and remove one each
$('nav > ul > li.has-submenu').children('a').each(function() {
$(this).append('<i class="fa fa-chevron-down"></i>');
$(this).on('click', function(e) {
.....
Or using your code if you had used find('a:first') it would have worked since you would be targeting only the first <a> in each of those class

Why can't I center my nav bar?

I am using jQuery to create a drop down nav menu and it works fine, but I can not get it to center on my page.
I have tried using align="center" in the div "menu", but that did not work. I then tried aligning it using the css for the div and the lis and uls, but that also did not work.
Here is my code
jQuery:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript">
</script>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript">
$(document).ready(function () {
$("#menu li").hover(function () {
$(this).children(":hidden").slideDown();
}, function(){
$(this).parent().find("ul").slideUp();
});
});
</script>
HTML:
<div id="menu">
<ul>
<li>Home
</li>
<li>test
<ul>
<li>drop1</li>
<li>drop2</li>
<li>drop3</li>
</ul>
</li>
<li>test
<ul>
<li>drop1</li>
<li>drop2</li>
</ul>
</li>
</ul>
</div>
CSS:
#menu {
height: 30px;
background-color: #26C7FF;
margin-left: 0;
margin-right: 0;
}
#menu li li:hover {
background-color: yellow;
cursor: pointer;
}
#menu ul, #menu li {
list-style-type: none;
padding: 0;
margin: 0;
}
#menu li {
float: left;
width: 120px;
list-style-type: none;
line-height: 30px;
text-align: center;
}
#menu li ul {
position: absolute;
background-color: #26C7FF;
display: none;
}
#menu li li {
float: none;
padding: 2px;
}
#menu a {
color: #000;
text-decoration: none;
}
Use display:inline-block; instead of floating the li elements and then use text-align:center; for the container ul.
#menu > ul > li {
display: inline-block;
}
Here is a working example:
http://codepen.io/taneleero/pen/MwojLV
Wrap it in a container that has a max-width of whatever width you'd like your menu to be:
.container {
max-width: 600px; // Or whatever
width: 100%;
margin: 0 auto;
}
#menu {
height: 30px;
background: #26C7FF;
}
<div class="container">
<div id="menu">
</div>
Please check this code. I think this is what you wanted.
< script type = "text/javascript" >
$(document).ready(function() {
$("#menu li").hover(function() {
$(this).children(":hidden").slideDown();
}, function() {
$(this).parent().find("ul").slideUp();
});
}); < /script>
#menu {
height: 30px;
background-color: #26C7FF;
margin-left: 0;
margin-right: 0;
}
#menu li li:hover {
background-color: yellow;
cursor: pointer;
}
#menu ul,
#menu li {
list-style-type: none;
padding: 0;
margin: 0;
text-align: center;
position: relative;
}
#menu li {
float: none;
width: 120px;
list-style-type: none;
line-height: 30px;
text-align: center;
display: inline-block;
}
#menu li ul {
position: absolute;
background-color: #26C7FF;
display: none;
left: 0;
right: 0;
}
#menu li li {
float: none;
padding: 2px;
}
#menu a {
color: #000;
text-decoration: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript">
</script>
<link rel="stylesheet" type="text/css" href="style.css">
<div id="menu">
<ul>
<li>Home
</li>
<li>test
<ul>
<li>drop1
</li>
<li>drop2
</li>
<li>drop3
</li>
</ul>
</li>
<li>test
<ul>
<li>drop1
</li>
<li>drop2
</li>
</ul>
</li>
</ul>
</div>
this is the JSFIDDLE link
Since you're setting your ordered list tags at a fixed width, the following css should fix your problem.
#menu ul {
width: 369px;
margin: 0 auto;
}
Here's a working jsfiddle.

Website Menu Bar Drop Down

I am working on a website for a client. For the menu/navigation bar, I created one for them (they were very specific) with dropdowns, but there is one problem--when you mouse over one of the items on the dropdown, it dissappears--check it out here http://www.brandonsdesigngroup.com/menu-expamle.html.
for the code, I call jquery from google API's, then there is the javascript, the CSS, and the actual content (in an unordered list).
Javascript:
<script type="text/javascript">
$(document).ready(function(){
$("#nav-one li").hover(
function(){ $("ul", this).fadeIn("fast"); },
function() { }
);
if (document.all) {
$("#nav-one li").hoverClass ("sfHover");
}
});
$.fn.hoverClass = function(c) {
return this.each(function(){
$(this).hover(
function() { $(this).addClass(c); },
function() { $(this).removeClass(c); }
);
});
};
</script>
CSS:
<style type="text/css">
.nav, .nav ul {
list-style: none;
margin: 0;
padding: 0;
height:20px
}
.nav {
z-index: 100;
position: relative;
}
.nav li {
border-left: 0px solid #000;
float: left;
margin: 0;
padding: 0;
position: relative;
font-family: Arial, Helvetica, sans-serif;
font-style:normal;
font-size:12px;
}
.nav li a, .nav li a:link, .nav li a:active, .nav li a:visited {
font:1.22em/25px "Arial Narrow", Arial, sans-serif letter-spacing:5px;
color: #FFFFFF;
display: block;
padding: 0 10px;
text-decoration: none;
text-style: narrow;
margin-right:26px;
}
.nav li a:hover {
margin-right:26px;
color: #FFFFFF;
}
#nav-one li:hover a,
#nav-one li.sfHover a {
color: #FFFFFF;
}
#nav-one li:hover ul a,
#nav-one li.sfHover ul a {
color: #FFFFFF;
height:20px;
background-image: url(menubar/transparent.png);
}
#nav-one li:hover ul a:hover,
#nav-one li.sfHover ul a:hover {
color:#FFFFFF;
background-image:url(menubar/transparent.png);
}
.nav ul {
border-bottom: 0px solid #FFFFFF;
list-style: none;
margin: 0;
width: 100px;
position: absolute;
top: -99999px;
left: 0px;
}
.nav li:hover ul,
.nav li.sfHover ul {
top: 22px;
}
.nav ul li {
border: 0;
float: none;
font-family: Arial, Helvetica, sans-serif;
font-style:normal;
font-size:10px;
}
.nav ul a {
border: 0px solid #000;
border-bottom: 0;
padding-right: 50px;
margin-bottom: 0px;
width: 130px;
white-space: nowrap;
}
.nav ul a:hover {
color: #FFFFFF;
}
</style>
<style type="text/css">
body {
width: auto;
height: auto;
background-color: #3A2C21;
}
</style>
HTML:
<td background="images/menu_bg.gif" height="25"><ul id="nav-one" class="nav">
<li>
HOME
</li>
<li>
PROFILE
<ul>
<li>ABOUT</li>
<li>PEOPLE</li>
<li>SERVICES</li>
<li>TRADE SHOWS</li>
</ul>
</li>
<li>
PORTFOLIO
<ul>
<li>ARTISTIC TILE</li>
<li>ATLANTIS</li>
<li>BLANCO</li>
<li>BUTLER"S OF FAR HILLS</li>
<li>HAMPTON FORGE</li>
<li>HILAND H. TURNER</li>
<li>MIELE</li>
<li>POGGENPOHL</li>
<li>THG FAUCETS</li>
<li>TOP KNOBS</li>
<li>VIXEN HILL</li>
</ul>
</li>
<li>
PUBLIC RELATIONS
<ul>
<li>PRESS ATTENTION</li>
<li>FRANK PR</li>
<li>HITS</li>
<li>MORE HITS</li>
<li>LEVERAGING PR</li>
</ul>
</li>
<li>
CONTACT
</li>
</ul>
Problem #1: Menu disappears before cursor can reach submenu.
Usually this is due to a gap between the <li> tag and the subnavigation <ul>. A gap of even one pixel will cause the navigation to disappear before the cursor can reach the submenu.
For instance, add a padding: 0 0 10px; to .nav li in your CSS, and the problem goes away.
You could also set a specific height for the <li> to cover the problem, too.
Problem #2: Menu disappears when cursor runs over the image slideshow.
As to the problem of your menu disappearing when you reach the point where your image slideshow and menu collide, that's due to a z-index problem.
You should set the .nav to have a z-index: 200 (or anything greater than 100, according to your slideshow -- I try to go overboard). This will make sure it sits above the gallery.
Javascript
<script>
sfHover = function() {
var sfEls = document.getElementById("navbar").getElementsByTagName("li");
for (var i=0; i<sfEls.length; i++) {
sfEls[i].onmouseover=function() {
this.className+=" hover";
}
sfEls[i].onmouseout=function() {
this.className=this.className.replace(new RegExp(" hover\\b"), "");
}
}
}
if (window.attachEvent) window.attachEvent("onload", sfHover);
</script>
html
Already a Member? Login
Become a Member?
Signup
Army
Navy
Airforce
I would use the Hover Intent plug-in. It is designed for exactly this kind of usage and helps provide a more robust dropdown.

Categories

Resources