I have a header and am trying to create a drop-down menu without Bootstrap.
When I click on a link, I want the drop-down menu to appear. It's hidden by default. I tried using jQuery to show the list.
HTML
<div class="menu">
<div class="menu_center">
Products
<ul>
<li>Clothing</li>
<li>Stationary</li>
<li>Other
</ul>
Promotions
About Us
<ul>
<li>Philosophy</li>
<li>Our Suppliers</li>
<li>Contact</li>
</ul>
Your Cart:
<ul>
<li>Tech{Yourself} T-Shirt: Blue, Large - $19.95</li>
<li>Tech{Yourself} Owl Plush Toy - $19.95</li>
<li><b>Total: $39.90</b> <button class="js-check-out">Check Out</button></li>
</ul>
</div>
</div>
CSS
html body{
font-family:'Open Sans',sans-serif;
font-size:16px;
line-height:18px;
color:#000;
font-weight:400;
}
.menu_center a {
text-decoration: none;
}
jQuery
$(document).ready(function() {
$(".menu_center ul").hide();
$(".menu_center > a").on("click", function() {
$(this).children("ul").show();
});
});
http://jsfiddle.net/9ov9za3r/1/
Not sure why this isn't working.
The ul element is not a child of the a element, you would need to do:
$(this).next("ul").show();
jsfiddle
Replace this:
$(this).children("ul").show();
by this:
$(this).next("ul").slideToggle();
The ul is not the children, its the next element right after the a tag
and you might want to use toggle(), fadeToggle() or slideToggle() rather than just show() to be able to hide the menu again when u click on it after it appears
Here is the JSFiddle demo
Related
I have this navbar it works how I want it too but my main problem is I want the dropdown menu to disappear by clicking any links on the menu because I am not sure what to add to my current code to get it to behave as desired. Thanks any help would be appreciated
<nav id="navbar">
<div class="logo">
<img src="log.png">
</div>
<ul>
<li>About</li>
<li>Contact</li>
<li>Project</li>
<li>Home</li>
</ul>
</nav>
Here is my JS
It works fine I just one the additional feature that I mentioned on the title since I don't know how to do it
<script type="text/javascript">
$(window).on('scroll', function()
{
if($(window).scrollTop())
{
$('nav').addClass('black');
}
else
{
$('nav').removeClass('black');
}
}
)
$(document).ready(function() {
$(".menu").on("click", function() {
$("nav ul").toggleClass("active");
});
})
Just add the nav ul li a to your click function. Since I don't know what your markup looks like here is a quick demo:
$(".menu, nav ul li a").on("click", function(e) {
e.preventDefault();
$("nav ul").toggleClass("active");
});
ul{
display:none;
}
ul.active{
display:block;
}
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<nav>
<button class="menu">
Menu
</button>
<ul>
<li>Link</li>
<li>Link</li>
<li>Link</li>
</ul>
</nav>
With jquery you can comma separate selectors. Since you already have the functionality to toggle the active class just add the nav ul li a to your existing function.
A CSS styling may be a potential solution.
all tags are displayed as blocks so in your CSS file add
.makeDisappear{
display:none
}
Although, I do recommend renaming your id for your navbar something a bit more unique.
so example jQuery would be:
$("a").on("click",function(){
document.getElementById("navbar").classList.add("makeDisappear");
//or simply $("#navbar").addClass("makeDisappear")
})
to make your nav bar reappear
change display:none to display:block
I've built a simple toggle menu that when clicked once shows a list of child elements and if clicked again hides those visible elements.
If a child element is clicked however I want it to visit that page only I cant seem to get it working? Is it to do with my prevent Default?
// Language select in global nav
$('.sub-lang').on('click', function(e) {
if ($(this).hasClass('active') && $(e.target).parent().hasClass('active')) {
$(this).removeClass('active');
$(this).css('height', 'auto');
$(this).children('ul').hide();
} else {
$(this).addClass('active');
$(this).css('height', $(this).find('ul').height() + 65);
$(this).children('ul').show();
}
e.preventDefault();
});
Here is the JsFiddle
Why don't you simple transform your main menu element in paragraph tag ?
or you could put an # inside your main menu element, and delete prevent default.
In this way you don't need to prevent default on your main elements.
Although google.com doesn't load inside an iFrame, you could check this fiddle. It works.
Look at this (with # in the anchors) fiddle
HTML
<ul style=" ">
<li class="sub-lang">
English
<ul style="">
<li>International</li>
<li>UK & Ireland</li>
</ul>
</li>
<li class="sub-lang">
Espanol
<ul style="">
<li>Español</li>
<li>España</li>
</ul>
</li>
<li class="sub-lang">
Francais
<ul style="">
<li>Français</li>
<li>France</li>
</ul>
</li>
</ul>
Add this line before your code
$('.sub-lang > a').removeAttr('href');
Remove
e.preventDefault();
this should work fine
You should add one condition for that.
if($(e.target).parent().hasClass('sub-lang') )
It will allow you to click on submenu.
// Language select in global nav
$('.sub-lang').on('click', function(e) {
if($(e.target).parent().hasClass('sub-lang') ){
if ($(this).hasClass('active') && $(e.target).parent().hasClass('active')) {
$(this).removeClass('active');
$(this).css('height', 'auto');
$(this).children('ul').hide();
} else {
$(this).addClass('active');
$(this).css('height', $(this).find('ul').height() + 65);
$(this).children('ul').show();
}
e.preventDefault();
}
});
ul li ul {
display: none;
z-index: 2;
right: 0;
background-color: #fff;
width: 250px;
}
ul li.active ul {
display: block;
text-align:left;
background: #f1f1f1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul style=" ">
<li class="sub-lang">
English
<ul style="">
<li>International</li>
<li>UK & Ireland</li>
</ul>
</li>
<li class="sub-lang">
Español
<ul style="">
<li>España</li>
</ul>
</li>
<li class="sub-lang">
Français
<ul style="">
<li>France</li>
</ul>
</li>
</ul>
Working Fiddle
Hope it helps.
Here Check This Out.
Explaination.
Instead of delegating the event on the whole li, I bound the event to all the immediate <a> children of the li, and then prevent the propagation for that specific element. So we don't have to figure out how to stop the event propagation (click in our case) to the children element.
Also the JSFiddle may have loading external iframe problems, so check the solution out here.
I think you have to add stopPropagation in your inside list items.
$('.sub-lang ul li').on('click', function(e) {
e.stopPropagation();
});
i have a section in the content area of my site that has a list of links that have sublinks in them.
so that the users click the least amount as possible, i figured a drop down menu would be best, then that link would take them into the page, etc.
i know nothing about javascript or jquery so all the examples i find are little to no use to me because i don't even know where to begin to modify them to suit my needs.
what i would like to have happen:
when a user clicks the link a list drops down from it with all the sub pages.
PAGE LINK 1
|--sub page
|--sub page
PAGE LINK 2
|--sub page
|--sub page
jsFiddle link: http://jsfiddle.net/hHn7b/
the only thing i need it to do is while it does toggle the display of the sub pages, i need it to also when another link is clicked it will close the previously opened drop down menu.
(think along the lines of how a radio button functions)
i am not scared to use javascript or even that jquery stuff on this if i need to, but i don't know enough to do it myself, and i don't have the time currently to attempt and learn how to or even enough to modify other's jquery code they post on other questions in this site.
Below is the code from the jsFiddle:
HTML:
<div class="dl_parent"><span onclick="toggle_visibility('dl_sub_dd');">PAGE LINK 1</span>
</div>
<div id="dl_sub_dd">
<ul>
<li>sub page</li>
<li>sub page</li>
</ul>
</div>
<!--end dept_links_sub-->
<div class="dl_parent"><span onclick="toggle_visibility('dl_sub_dd1');">PAGE LINK 2</span>
</div>
<div id="dl_sub_dd1">
<ul>
<li>sub page</li>
<li>sub page</li>
</ul>
</div>
CSS:
span {
cursor:pointer;
}
#dl_sub_dd, #dl_sub_dd1 {
display:none;
}
JS:
function toggle_visibility(id) {
var e = document.getElementById(id);
if (e.style.display == 'block') e.style.display = 'none';
else e.style.display = 'block';
}
Here:
Fiddle: http://jsfiddle.net/nkKja/
I used jQuery for this, as it makes things so much easier, and you said you had no problem with that.
What happens:
When a link is clicked, this line var submenu = $(this).parent().children('.dl_sub_dd'); first goes to the parent-element of the link, and from there searches for a child-element with class .dl_sub_dd.
Next, the code checks whether that child-element is visible. If not, it makes it visible (first hiding any other submenu's that might be showing. If it is visible, the code only hides the submenu for which the link was clicked.
HTML: (both elements are identical, except for the 'PAGE LINK 1' text)
<div class="dl_parent">
<div class="dl_link">PAGE LINK 1</div>
<div class="dl_sub_dd">
<ul>
<li>sub page</li>
<li>sub page</li>
</ul>
</div>
</div>
CSS:
.dl_link {
cursor:pointer;
}
.dl_sub_dd {
display:none;
}
JS:
$(window).on('load',function(){
$('.dl_link').click(function(){
var submenu = $(this).parent().children('.dl_sub_dd');
if (submenu.css('display') == 'none') {
$('.dl_sub_dd').hide(); //first hide any previously showing submenu's
submenu.show(); //then show the current submenu
} else {
submenu.hide(); //hide the current submenu again
}
});
});
UPDATE
When implementing the code on your website, I always like to be real organized. I always do it like this:
Have one index.php. In that you put require('page/websitename.php');
In the page/websitename.php, you put your HTML-page.
All your JS is in external files, and you link to that on your page in the <head></head> like this:
<script type="text/javascript" src="js/websitename.js"></script>
Link to library files (like jQuery) like this:
<script type="text/javascript" src="lib/jquery/jquery.min.js"></script>
Php-files are in a php-foldes, images in a img-folder, etc
You'll have a structure like this:
▼ [Main folder]
css
websitename.admin.css
websitename.css
websitename.login.css
► img
js
websitename.admin.js
websitename.js
▼ lib
jquery
jquery.min.js
[other library]
[other library]
page
websitename.admin.php
websitename.login.php
websitename.php
► php
index.php
The php-folder (which is closed in this overbiew) might have another subfolder "admin" for php-scripts used exclusively by the admin page.
The img-folder may also have a sub-structure..
You get the point:)
Here's a script I actually use in production that does exactly what you're looking for. Basically the same idea as what #myfunkyside already posted, but with a few small enhancements.
It uses jQuery's slide animation for smoother user interaction
You can nest sub menus in the main menu as deep as you want
When the page loads, it opens the menu and highlights the link to the current page by matching it to the URL, which helps the user orient somewhat. This function is hyphen and dash friendly.
jsFiddle here: http://jsfiddle.net/contendia/ddXBU/4/
CSS:
<style>
#leftmenu h3 {
margin:0;
padding:2px 5px;
border-top:1px solid #006699;
border-bottom:1px solid #003366;
cursor:pointer;
background-color:#0e559d;
color:#ffffff;
text-align:left;
}
#leftmenu h3:hover {
background-color:#003366;
}
#leftmenu > ul {
margin:0;
padding:0;
}
#leftmenu > ul li {
padding-left:10px;
list-style-type:none;
}
#leftmenu > ul li a {
color:#666666;
font-weight:bold;
text-decoration:none;
}
#leftmenu > ul li a:hover {
text-decoration:underline;
}
#leftmenu .current {
color:#006699;
text-decoration:underline;
}
</style>
JS:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// Get the URI path and strip the leading slash
var path = $(location).attr('pathname').replace(/\//, "");
// Get and append the querystring
path += $(location).attr('search');
// Hide everything
$('#leftmenu ul').hide();
// Go up 2 levels (a > li > ul) and open. Hide all others.
$('#leftmenu a[href="' + path + '"]').addClass('current').parent().parent().slideDown();
$('#leftmenu h3').click(
function() {
var $this = $(this);
$this.next('ul').siblings('ul').slideUp();
$this.next('ul').find('ul').slideUp();
$this.next().slideToggle(300);
});
});
</script>
HTML:
<div id="leftmenu">
<h3>First Menu</h3>
<ul>
<li>Underscores</li>
<li>Hyphens</li>
</ul>
<h3>Second Menu</h3>
<ul>
<li>Underscores</li>
<li>Hyphens</li>
<li>
<h3>Sub Menu</h3>
<ul>
<li>Underscores</li>
<li>Hyphens</li>
</ul>
</li>
</ul>
</div>
Let me start by saying I know this is a duplicate, however I couldn't find a solution by looking through previous answers so I was hoping someone can explain what I'm doing wrong with this.
This is part of a menu output by a php script:
<ul id="mtk_main_menu">
<li class="mtk_topmenu" onMouseOver="showMenu('mtk_submenu_0', 'mtk_div_submenu_0');">Manager Options
<div id="mtk_div_submenu_0">
<ul id="mtk_submenu_0">
<li class="mtk_submenu">Preferences</li>
<li class="mtk_submenu">Employee Options</li>
</ul>
</div>
</li>
with the following as my script as per https://stackoverflow.com/a/11842992, which should show each submenu when hovering its parent container
function showMenu(a,b) {
$(a).hover(
function(){
$(b).show();
},
function(){
$(b).hide();
})
}
Javascript and CSS being my weak suits, could someone tell me where my problem is? I feel like onMouseOver doesn't work the way I would expect it to. However I am still learning to manipulate the DOM, please bear with me, thank you!
Edited to reflect missingno's suggestions
For simple scenarios, i'd rather stay away from using JS
Heres how
HTML
<ul id="mtk_main_menu">
<li class="mtk_topmenu" onMouseOver="showMenu('mtk_submenu_0, mtk_div_submenu_0');">Manager Options
<div id="mtk_div_submenu_0">
<ul id="mtk_submenu_0">
<li class="mtk_submenu">Preferences</li>
<li class="mtk_submenu">Employee Options</li>
</ul>
</div>
</li>
CSS
#mtk_main_menu:before,
#mtk_main_menu:after {
content:"";
display:table;
clear:both;
}
#mtk_main_menu {
*zoom:1;
}
#mtk_main_menu > li {
position:relative;
float:left;
}
#mtk_main_menu > li > div {
position:absolute;
left:-999px;
background:grey;
}
#mtk_main_menu > li:hover > div {
left:0;
}
That will do the trick
Fiddle: http://jsfiddle.net/Varinder/7pXSw/
Edit
If you really want to go the JS way - heres how:
HTML
<ul id="mtk_main_menu">
<li class="mtk_topmenu" onMouseOver="showMenu('mtk_submenu_0, mtk_div_submenu_0');">Manager Options
<div id="mtk_div_submenu_0">
<ul id="mtk_submenu_0">
<li class="mtk_submenu">Preferences</li>
<li class="mtk_submenu">Employee Options</li>
</ul>
</div>
</li>
CSS
#mtk_main_menu:before,
#mtk_main_menu:after {
content:"";
display:table;
clear:both;
}
#mtk_main_menu {
*zoom:1;
}
#mtk_main_menu > li {
position:relative;
float:left;
}
#mtk_main_menu > li > div {
position:absolute;
display:none;
/*left:-999px;*/
background:grey;
}
#mtk_main_menu > li:hover > div {
/*left:0;*/
}
JS
function showMenu( args ) {
var arguments = args.split(",");
var submenuWrapper = arguments[1].replace(" ", "");
var $subMenuWrapper = $( "#" + submenuWrapper );
$subMenuWrapper.show();
var $menuItem = $subMenuWrapper.closest("li");
$menuItem.on("mouseout", function() {
$subMenuWrapper.hide();
$(this).off("mouseout");
});
}
Fiddle: http://jsfiddle.net/Varinder/vnwy3/1/
You are calling the event handler with a single string parameter instead of two. Try changing
showMenu('mtk_submenu_0, mtk_div_submenu_0')
into
showMenu('mtk_submenu_0', 'mtk_div_submenu_0')
Additionally, inside your script you should use are using literal strings instead of using your parameters
//This looks for an element of class "a"
$("a").hover(
//This uses the contents of the `a` variable instead:
$(a).hover(
Finally, your function is using 'mtk_submenu_0' as a jquery selector. This searches for a class instead of an id. Change the selector to add a "#" on front or change your jquery logic to not need ids (for example, you could create selectors to search for the first div and ul descendants of the current element.
By doing what you are doing, every time the onMouseOver event is triggered, you're attaching the jQuery hover event. Each time you're attaching another listener.
Instead, initialize your event on document ready:
$(function () {
$("#tk_div_submenu_0").hover(
function(){
$("#mtk_submenu_0").show();
},
function(){
$("#mtk_submenu_0").hide();
})
);
});
That will initialize it when the document is ready, and it will initialize it once.
Then just remove your onMouseOver event from the HTML.
<li class="mtk_topmenu">Manager Options ... </li>
First, you're going the long way around the problem. jQuery has a built in toggle method that performs the show/hide for you. Secondly you're putting the hover call on the child element of the item you're trying to show on hover. Here's an updated version of your code:
<ul id="mtk_main_menu">
<li class="mtk_topmenu" onMouseOver="showMenu(this,'mtk_div_submenu_0');">
Manager Options
<div id="mtk_div_submenu_0">
<ul id="mtk_submenu_0">
<li class="mtk_submenu">Preferences</li>
<li class="mtk_submenu">Employee Options</li>
</ul>
</div>
</li>
</ul>
JS:
function showMenu(a,b) {
var divStr = '#' + a.id + " div";
$(divStr).toggle();
}
I used the hover event on the LI element as it makes more sense in this case.
Here it is in a fiddle: http://jsfiddle.net/3Ecrq/
One thing I find strange about your code is that the first div you mention, mtk_submenu_0, is inside the div you are showing / hiding, mtk_div_submenu_0. Once you hide the outer div, the inner div cannot be 'hovered over', thus preventing it from being shown again.
To ensure the inner div does not get hidden, try something like this:
HTML:
<ul id="mtk_main_menu">
<li class="mtk_topmenu">Manager Options
<div id="mtk_div_submenu_0">
<ul id="mtk_submenu_0">
<li class="mtk_submenu">Preferences</li>
<li class="mtk_submenu">Employee Options</li>
</ul>
</div>
</li>
Javascript:
$(document).ready(function() {
$('.mtk_topmenu').hover(
function() {
$('#mtk_div_submenu_0').show();
},
function() {
$('#mtk_div_submenu_0').hide();
});
});
Because of your line:
<li class="mtk_topmenu" onMouseOver="showMenu('mtk_submenu_0', 'mtk_div_submenu_0');">
I assumed you were looking to have the mtk_div_submenu_0 div show / hide whenever the text Manager Options is moused over. Hopefully this helps!
i've got a problem with the CSS. Normally I can get it right, but now it's just not working for me.
Got the menu-code
<nav>
<ul class="ca-menua">
<li class="home"><div class="ca-icona">O</div><span>Home</span>
</li>
<li class="info"><div class="ca-icona">e</div><span>Info</span>
</li>
<li class="komp"><div class="ca-icona">S</div><span>Kompetencer</span>
</li>
<li class="cases"><div class="ca-icona">F</div><span>Cases</span>
</li>
<li class="kontakt"><div class="ca-icona">#</div><span>Kontakt</span>
</li>
</ul>
</nav>
The i've got the javascript which add's the active class.
<script type="text/javascript">
$(document).ready(function(){
$('.home a.tooltip').addClass('active');
});
</script>
<script type="text/javascript">
$(function() {
$('a.tooltip').click(function(e) {
var $this = $(this);
$("#nav").load($this.attr('href'));
$('a.tooltip').removeClass('active');
$(this).addClass('active');
// prevent default link click
e.preventDefault();
})
});
</script>
This works fine, and adds the class, but I just can't get the CSS right!
I need some help with a prob. small problem.
The website link is: HERE
THE CSS:
a.tooltop.active{
color: #f3cb12;
font-size: 50px;
}
Just add the div part into a.tooltip.active selector so you get something like this:
a.tooltip.active div {
color: #F3CB12;
font-size: 50px;
}
I have assumed that you are trying to get the icon bigger and highlighted if the menu item is active. The problem is that it is not the anchor that should be getting new styles, but the child div element.