I am trying to add a .selected state to my navigation menu using jquery. I can see that it is trying to work, but after all is said and done, the style does not "stay". It should be white after it is clicked.
HTML:
<ul id="coolMenu">
<li class="end"></li>
<li class="mid">products
<ul class="mama">
<li class="uno"><a href="http://www.preworkoutforwomen.com"
onclick="_gaq.push(['_link', 'http://www.preworkoutforwomen.com']); return false;">Athena PreWorkout</a></li>
</ul>
</li>
<li class="midx">u.blog </li>
<li class="midx">athletes</li>
<li class="midx">about us</li>
<li class="midx">contact </li>
<li class="shop">shop </li>
</ul>
CSS:
#coolMenu {
list-style: none;
float:left;
padding-left:7.5px;
padding-right:0px;
position:relative;
}
#coolMenu ul {
-webkit-box-shadow: 0px 3px 3px 0px #4a4a4a;
border-bottom-left-radius:5px;
-moz-border-bottom-left-radius:5px;
-moz-box-shadow: 0px 3px 3px 0px #4a4a4a;
box-shadow: 0px 3px 3px 0px #4a4a4a;
}
#coolMenu .selected {
background-position:bottom !important;
color:black !important;
}
#coolMenu li {
width:145px;
height:48px;
display:inline-block;
float:left;
background-image:url(../images/misc/images/retina-sprite_03.png);
-webkit-background-size: 750px 150px;
-o-background-size: 750px 150px;
-moz-background-size: 750px 150px;
background-size: 750px 150px;
background-position: -301px -1px;
-webkit-transition: all 200ms ease-in-out;
-moz-transition: all 200ms ease-in-out;
-o-transition: all 200ms ease-in-out;
transition: all 200ms ease-in-out;
}
#coolMenu > li.end {
border-bottom-left-radius:7px;
-moz-border-bottom-left-radius:7px;
border-top-left-radius:7px;
-moz-border-top-left-radius:7px;
background-position: -601px -1px;
text-align:center;
}
#coolMenu > li.shop {
text-align:center;
border-left-style:ridge;
border-left-color:#333;
border-left-width:thin;
border-bottom-right-radius:7px;
-moz-border-bottom-right-radius:7px;
border-top-right-radius:7px;
-moz-border-top-right-radius:7px;
}
#coolMenu > li.mid {
text-align:center;
border-left-style:ridge;
border-left-color:#333;
border-left-width:thin;
}
#coolMenu > li.midx {
text-align:center;
border-left-style:ridge;
border-left-color:#333;
border-left-width:thin;
}
#coolMenu li a {
display: block;
height: 2.4em;
line-height: 2.1em;
padding: 0px;
text-decoration: none;
}
#coolMenu uno,dos,tres a {
display: block;
height: .5em;
line-height: 1em;
padding: 0px;
text-decoration: none;
}
#coolMenu ul {
position: absolute;
display: none;
z-index: 999;
padding: 0px;
}
#coolMenu ul li {
}
#coolMenu ul li a {
}
#coolMenu li:hover ul.noJS {
display: block;
}
Javascript:
$(document).ready(function(){
$("#coolMenu li").click(function() {
// First remove class "active" from currently active tab
$("#coolMenu li").removeClass('selected, end, mid, midx, shop');
// Now add class "active" to the selected/clicked tab
$(this).addClass("selected");
});
});
When you click on links page is refreshed. Change them from :
<li class="end"></li>
to
<li class="end"></li>
If you want to test without refresh page.
EDIT : you can also changeyour javascript file to :
$(document).ready(function(){
$("#coolMenu li").click(function() {
// First remove class "active" from currently active tab
$("#coolMenu li").removeClass('selected, end, mid, midx, shop');
// Now add class "active" to the selected/clicked tab
$(this).addClass("selected");
//CHANGED
return false ;
});
});
This isn't in answer to your question as I'm pretty sure the other commenters have already covered that. I just want to say, I tidied up your CSS code because it was in a bit of a mess. Also you should always put the unprefixed CSS3 property under the prefixed ones (i.e border-radius: 5px; should go under -webkit-border-radius: 5px;), so that when the browser vendors drop the prefixed versions (most modern browsers don't use prefixes any more for a lot of CSS3 things, border-radius included. You should still include the prefixed versions for older versions of the browsers though.), the unprefixed versions will overwrite the obsolete prefixed versions.
Secondly, you don't seem to use shorthand CSS much, which can massively improve the effecieny of CSS. E.g background: /* code */ can cover background-image, background-position, background-size, background-color etc. Read this for more info about Shorthand CSS.
It is because after click event the clicked page opens and reloads entire page. it is completely another page after the click.
I am not sure what you actually try to do but if your pages are html, you should set the selected class in html file
for product.html
<li class="selected">products
if you are load the content by JS such as displaying another div or load by AJAX.
You should use event.preventDefault(); after the addClass function.
EDIT:
If you want to select class after load try something like this :
$(document).ready(function(){
$("#coolMenu li a").each(function () {
if (location.href.indexOf(this.href) > -1)
{
$(this).parent().attr("class", "selected");
return false;
}
});
});
Hope it works I couldn t test it.
Related
in my MVC app I have a left menu which I need the active link css to keep style after reload
in my css I have
.navleft li a:hover {
background: url('../Content/images/nav.png') no-repeat;
background-position: -232px 0;
color: #fff;
left: -6px;
padding: 19px 18px 19px 40px;
margin-top: -10px;
}
.navleft li a:active {
background: url('../Content/images/nav_active.png') no-repeat;
background-position: -232px 0;
color: #fff;
left: -6px;
padding: 19px 18px 19px 40px;
margin-top: -10px;
}
and in my view
<ul class="navleft">
#foreach (var item in Model.CLeftMenu.ToList())
{
foreach (var content in Model.LeftSiteContent.ToList())
{
if (item.LeftMenuID == content.LeftMenuID)
{
<li><a href="#Url.Action("Details", "LeftContents", new { id =
#content.LeftContentID })">#item.LeftMenuTitle</a></li>
}
}
}
</ul>
which dynamically builds the menu . The hover statement it works fine but no the active. When I inspect the page it renders
Services
It takes the class active by its own.
When I change my css to
.active {
background: url('../Content/images/nav_active.png') no-repeat;
background-position: -232px 0;
color: #fff;
left: -6px;
padding: 19px 18px 19px 40px;
margin-top: -10px;
}
it works. But then all the active links in my site takes this style (which is and the reasonable).
How can I achive this just for the leftmenu? Do I have to declare current as well? since I read that the pseudo code :active is just for the moment the user clicks on the item. I have seen this css class active after page reload but it doesn't work for me.
thank you
The :active CSS pseudo-class represents an element (such as a button) that is being activated by the user. When using a mouse, "activation" typically starts when the user presses down the primary mouse button and ends when it is released. The :active pseudo-class is commonly used on and elements, but may be used on other elements, too.
enter link description here
there is no :active
class need to be defined as .active
.navleft li a:active rename to .navleft li a.active {
I have created a jfiddle for this problem at: JSFiddle showing menu problems
I am trying to create a cool menu using jquery and css3 mainly because of familiarity. I would be willing to switch to full CSS3, but I am less sure of how to do that. I have several problems that I cannot seem to fix. The code is as follows:
javascript:
(function ($) {
$.fn.hoverIntent = function (f, g) {
// default configuration options
var cfg = {
sensitivity: 7,
interval: 100,
timeout: 0
};
// override configuration options with user supplied object
cfg = $.extend(cfg, g ? {
over: f,
out: g
} : f);
// instantiate variables
// cX, cY = current X and Y position of mouse, updated by mousemove event
// pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
var cX, cY, pX, pY;
// A private function for getting mouse position
var track = function (ev) {
cX = ev.pageX;
cY = ev.pageY;
};
// A private function for comparing current and previous mouse position
var compare = function (ev, ob) {
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
// compare mouse positions to see if they've crossed the threshold
if ((Math.abs(pX - cX) + Math.abs(pY - cY)) < cfg.sensitivity) {
$(ob).unbind("mousemove", track);
// set hoverIntent state to true (so mouseOut can be called)
ob.hoverIntent_s = 1;
return cfg.over.apply(ob, [ev]);
} else {
// set previous coordinates for next time
pX = cX;
pY = cY;
// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
ob.hoverIntent_t = setTimeout(function () {
compare(ev, ob);
}, cfg.interval);
}
};
// A private function for delaying the mouseOut function
var delay = function (ev, ob) {
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
ob.hoverIntent_s = 0;
return cfg.out.apply(ob, [ev]);
};
// A private function for handling mouse 'hovering'
var handleHover = function (e) {
// next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
while (p && p != this) {
try {
p = p.parentNode;
} catch (e) {
p = this;
}
}
if (p == this) {
return false;
}
// copy objects to be passed into t (required for event object to be passed in IE)
var ev = jQuery.extend({}, e);
var ob = this;
// cancel hoverIntent timer if it exists
if (ob.hoverIntent_t) {
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
}
// else e.type == "onmouseover"
if (e.type == "mouseover") {
// set "previous" X and Y position based on initial entry point
pX = ev.pageX;
pY = ev.pageY;
// update "current" X and Y position based on mousemove
$(ob).bind("mousemove", track);
// start polling interval (self-calling timeout) to compare mouse coordinates over time
if (ob.hoverIntent_s != 1) {
ob.hoverIntent_t = setTimeout(function () {
compare(ev, ob);
}, cfg.interval);
}
// else e.type == "onmouseout"
} else {
// unbind expensive mousemove event
$(ob).unbind("mousemove", track);
// if hoverIntent state is true, then call the mouseOut function after the specified delay
if (ob.hoverIntent_s == 1) {
ob.hoverIntent_t = setTimeout(function () {
delay(ev, ob);
}, cfg.timeout);
}
}
};
// bind the function to the two event listeners
return this.mouseover(handleHover).mouseout(handleHover);
};
})(jQuery);
$(function () {
var config = {
sensitivity: 3, // number = sensitivity threshold (must be 1 or higher)
interval: 200, // number = milliseconds for onMouseOver polling interval
over: doOpen, // function = onMouseOver callback (REQUIRED)
timeout: 200, // number = milliseconds delay before onMouseOut
out: doClose // function = onMouseOut callback (REQUIRED)
};
function doOpen() {
$(this).addClass("hover");
$('ul:first', this).css('visibility', 'visible');
}
function doClose() {
$(this).removeClass("hover");
$('ul:first', this).css('visibility', 'hidden');
}
$("ul.dropdown li").hoverIntent(config);
$("ul.dropdown li ul li:has(ul)").find("a:first").append(" » ");
$("ul.dropdown li ul li:has(ul)").find("span:first").append(" » ");
});
CSS3:
.main_nav {
background-color:#ffffff;
text-align:center;
float:left;
height:50px;
}
.main_nav ul{
list-style:outside none none !important;
text-align: center;
display: inline;
width: 80%;
}
/*
LEVEL ONE
*/
ul.dropdown { position: relative; white-space: nowrap;text-wrap: none;}
ul.dropdown li { font-weight: bold; float: left; background: #ffffff; color: #4b2c17; }
ul.dropdown a:hover { color: #ffffff; }
ul.dropdown a:active { color: #ffa500; }
ul.dropdown li a { display: block; padding: 4px 8px; border-right: 1px solid #333;
color: #222; }
ul.dropdown li:last-child a { border-right: none; } /* Doesn't work in IE */
ul.dropdown li.hover,
ul.dropdown li:hover { background: rgb(214, 210, 0); color: #ffffff; position: relative; }
ul.dropdown li.hover a { color: black; }
ul.dropdown li:hover h4 {background: #ffffff;color: #4b2c17;}
/*
LEVEL TWO
*/
ul.dropdown ul { visibility: hidden; position: absolute; top: 100%; left: 0; padding-left: 0px !important;}
ul.dropdown ul li { font-weight: normal; background: #ffffff; color: #4b2c17;
border-bottom: 1px solid #222; float: none; }
/* IE 6 & 7 Needs Inline Block */
ul.dropdown ul li a { border-right: none; width: 100%; display: inline-block; }
/*
LEVEL THREE
*/
ul.dropdown ul ul { left: 100%; top: 0; }
ul.dropdown li:hover > ul { visibility: visible; }
/*
LEVEL Four
*/
ul.dropdown ul ul ul { left: 100%; top: 0; }
ul.dropdown ul ul li:hover > ul { visibility: visible; }
and the HTML:
<div class="main_nav">
<ul class="dropdown">
<li>Home</li>
<li>User
<ul class="sub_menu">
<li class="subnavhead"><h3>New Users</h3></li>
<li>Add New User</li>
<li>Validate Users</li>
<li class="subnavhead"><h3>Current Users</h3></li>
<li>Edit User Information</li>
</ul>
</li>
<li class="topnav">Head 2
<ul class="sub_menu">
<li><a target="new" href="#">Subhead 1</a></li>
<li class="subnavhead"><h4><span>Section Group</span></h4>
<ul class="thirdnav">
<li>Subgroup head 1
<ul class="thirdnav">
<li>Subgroup item 1</li>
<li>Subgroup item 2</li>
</ul>
</li>
<li>Subgroup head 2
<ul class="thirdnav">
<li><span>Subgroup item head 1</span>
<ul class="thirdnav">
<li>third level 1</li>
<li>third level 2</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
These codes are supposed to generate a multi-level menu with the ability to track what is highlighted; however, there are several abberrant behaviors within this that I have been currently unable to fix.
The first is the width for the main navigation bar. I have been unable to get the menu to spread out to fill the menu bar even 80% regardless of the width parameter I have tried to define.
The second is the width of the LI on the drop-down menu components. As you can see I am able to prevent the line from wrapping, however as shown, the <li> does not stretch the width of the longest piece of text. Along with this, you see the highlight isn't consistent and I do not know why. I have tried multiple variations and no success.
The last problem is why that stupid >> is showing up on the last html link under sugroup head 2. The logic doesn't fit that, but it seems to show up.
Any help would be greatly appreciated!
Thanks!
Jon
If I understood correctly the issues I think I've resolved 2 and 3. About issue number 1 I simply don't understand what you mean... You want the whole menu to take up the whole page's width? If you could clarify it would be really helpful.
Anyway, for issue number 2 (again, if I understood it correctly) you can make the menu take up the width of the longest item by disabling the wrapping and setting the width to 100%:
ul.dropdown ul li {
font-weight: normal;
background: #ffffff;
color: #4b2c17;
border-bottom: 1px solid #222;
width: 100%;
white-space:nowrap;
}
For issue number 3, Prachit had it right. It's the :has jQuery selector combined with the .find that's giving you trouble, since the a tag for "third level 1" is the first descendent a tag of a li that matches your selector $("ul.dropdown li ul li:has(ul)").find(" a:first"). In this case you should be looking only for direct childs of the li that matches your selector, hence your line would turn into:
$("ul.dropdown li ul li:has(ul)").find("> a:first").append(" » ");
Anyway, I've updated your fiddle here: http://jsfiddle.net/tzn1x7uq/5/
Hope I could help.
The other answers appear to have the good solutions for issues 2 & 3. When using position:absolute the children's height and width do not adhere like they normally do. Using white-space: nowrap will correct that (although using width:100% won't make a difference).
This line:
$("ul.dropdown li ul li:has(ul)").find("> a:first").append(" » ");
Works fine, there's other ways to target this besides :has() but it works. You can correct the hover issue of "head 2" > "section group" by removing the background from the following rule:
ul.dropdown li:hover h4 {background: #ffffff;color: #4b2c17;}
Lastly is the issue of not being able to set the width. There's a few things that need to happen. For one be sure to set the width on the document:
html, body{
width: 100%;
}
Next you need to add the same to all parents (percentage width only works if the parent has a defined width as well). So start with .main_nav:
.main_nav {
width: 100%; //add
background-color:#ffffff;
text-align:center;
height:50px;
}
On of the biggest reasons you're having issues is because of .main_nav ul being set to display: inline. inline doesn't not respect it's children's width/height therefore calling width: 100% will have no effect on it. Change to inline-block or just block and now add your width:
.main_nav ul{
width: 100%; //add
list-style:outside none none !important;
text-align: center;
display: inline-block; //add
padding: 0; //clear the default padding set on ul elements
}
Next, Your list items are floating, you'll need to clear those. Typically overflow:hidden is a good approach for clearing floats but in this case you have subnavs that will "overflow" your content so you're better off using a clearfix:
.main_nav ul:after{
content: "";
display: block;
clear: both;
}
Now you can set the size on your li's:
ul.dropdown li { width:33%; font-weight: bold; float: left; background: #ffffff; color: #4b2c17; }
Since your styles are being inherited through shared targeting, you need to overwrite the previous width of 33% with width: 100% for your subnav lis:
ul.dropdown ul li { font-weight: normal; background: #ffffff; color: #4b2c17; border-bottom: 1px solid #222; float: none; width: 100%; //add }
Now your list will take the full width. You have other issues, for one, using visibility: hidden is not a great idea. While the element is "hidden" from sight, it still takes up room on the page (as you will see if you scroll right and there is a lot of excess space). There's also the fact that your "head 2" menu has so many subnavs and stretches so far to the right that it's not ideal to be tucked into the corner. You may want to revisit the way it displays. Perhaps have it just drop downwards instead of two the right. Also just a UI/UX tip, having so many levels of dropdowns is not well liked for a user. But that's going to be up to you. Structurally this could use a lot of work, you should take advantage of class names so you don't have children inheriting unwarranted styles but I hope this sets you on the right path:
FIDDLE
you can use it.
<style>
body {
padding: 20px 50px 150px;
font-size: 13px;
text-align: center;
/* background: #E3CAA1;*/
}
ul.dr_menu {
text-align: left;
display: inline;
margin: 0;
padding: 15px 4px 17px 0;
list-style: none;
/*-webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);
-moz-box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);
box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);*/
}
ul.dr_menu li {
font: bold 12px/18px;
display: inline-block;
margin-right: -4px;
position: relative;
padding: 15px 20px;
/* background: #fff;*/
cursor: pointer;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
ul.dr_menu li:hover {
background: #0b86c8;
color: #fff;
}
ul.dr_menu li ul {
padding: 0;
position: absolute;
top: 48px;
left: 0;
width: 150px;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
display: none;
opacity: 0;
visibility: hidden;
-webkit-transiton: opacity 0.2s;
-moz-transition: opacity 0.2s;
-ms-transition: opacity 0.2s;
-o-transition: opacity 0.2s;
-transition: opacity 0.2s;
}
ul.dr_menu li ul li {
background: #0b86c8;
display: block;
color: #fff;
text-shadow: 0 -1px 0 #000;
}
ul.dr_menu li ul li:hover { background: #666; }
ul.dr_menu li:hover ul {
display: block;
opacity: 1;
visibility: visible;
}
</style>
<body>
<ul class="dr_menu">
<li>
Add Management
<ul>
<li>My Add</li>
</ul>
</li>
<li>
API Management
<ul>
<li>Create API</li>
<li>Manage API</li>
<li>Test API</li>
<li>Document API</li>
</ul>
</li>
</ul>
</body>
The width of main navigation bar does not spread because .main_nav have float: left;, so if you added width to li in percentage it won't spread. You can add width to .main_nav and then to li in percentage, it will spread along the width of .main_nav.
Set width of li on drop-down to get desired width drop-down. Not sure what you mean about highlight inconsistent, if you mean about extra white-spaces, it is because heading tags h3 and h4 have some default padding and margin. Set margin and padding to 0 for h3 and h4.
The >> shows up because you have used has selector in $("ul.dropdown li ul li:has(ul)").find("a:first").append(" » ");. has matches if tag exists anywhere among its descendants, not just as a direct child.
is this what youre looking for? http://jsfiddle.net/tzn1x7uq/7/
1a. Main Menu is 100% width: width: 100%; /*ADDED LINE*/
1b. Menu links take up more space:
ul.dropdown li a {
display: block; padding: 4px 30px; border-right: 1px solid #333; color: #222;
} /*ADDED padding 30px*/
prevent line wrapping:
ul li {white-space: nowrap;} /*ADDED LINE*/
2b. weird highlighting stuff:
h3{ margin: 0px;}
also you have a <h4><span>text here</span></h4>, i changed it to <h3>Text here</h3>
random >> caused by »
/* COMMENTED OUT: GAVE YOU THE >> things
$("ul.dropdown li ul li:has(ul)").find("a:first").append(" » ");
$("ul.dropdown li ul li:has(ul)").find("span:first").append(" » ");
*/
hope this helps!
You can have the hover effects using CSS only buddy.
<div id="navigation">
<ul class="menu">
<li>Home</li>
<li>User
<ul class="sub-menu">
<li>
<h3>New Users</h3>
Add New User
</li>
<li>Validate Users</li>
<li>
<h3>Current Users</h3>
Edit User Information
</li>
</ul>
</li>
<li>User 2
<ul class="sub-menu">
<li>
<h3>New Users</h3>
Add New User
<ul class="sub-menu">
<li>
<h3>New Users 2</h3>
Add New User
<ul class="sub-menu">
<li>
<h3>New Users 3</h3>
Add New User
</li>
<li>Validate Users</li>
<li>
<h3>Current Users</h3>
Edit User Information
</li>
</ul>
</li>
<li>Validate Users</li>
<li>
<h3>Current Users</h3>
Edit User Information
</li>
</ul>
</li>
<li>Validate Users</li>
<li>
<h3>Current Users</h3>
Edit User Information
</li>
</ul>
</li>
<li>User 3
<ul class="sub-menu">
<li>
<h3>New Users</h3>
Add New User
</li>
<li>Validate Users</li>
<li>
<h3>Current Users</h3>
Edit User Information
</li>
</ul>
</li>
</ul>
For CSS
#navigation:before,
#navigation:after { clear: both; content: ' '; display: block; }
#navigation ul { padding: 0; }
#navigation li { float: left; list-style: none; position: relative; }
#navigation li a { display: block; padding: 5px 15px; text-decoration: none; white-space: nowrap; }
#navigation li a:hover { background-color: #222; color: #fff; }
#navigation li ul,
#navigation li:hover ul ul,
#navigation li li:hover ul ul { display: none; position: absolute; }
#navigation li:hover ul,
#navigation li li:hover ul,
#navigation li li li:hover ul { display: block; }
#navigation li li { float: none; }
#navigation ul ul ul { left: 100%; top: 0;}
h3 { margin: 0; }
js fiddle DEMO
I need to assign .dropdown .has-panel ul .dd-panel:nth-child(2) different top:x values but it seems my nth-child is not working correct as i may be doing something wrong.
fiddle sample http://jsfiddle.net/Ed9nk/4/
I need to align Level 3/ Grand Child menus at top of the container like level 2 /Child menus so that respective level3 me menus always show at top.
i added following css
/* has set top: -64px; manually so that Parent One > Child Menu> Grand Child align to top*/
.dropdown ul ul .dd-panel {
background: none repeat scroll 0 0 red;
border-left: 0px solid #30a784;
border-right: 0px solid #008438;
bottom: 0;
display: none;
font-size: 11px;
height: 100%;
left: 175px;
line-height: 15px;
min-height: 100px;
padding: 10px;
position: absolute;
text-align: justify;
top: -64px;
width: 400px;
}
.dropdown .has-panel ul .dd-panel:nth-child(2)
{
top: -64px;
background-color:green;
}
.dropdown .has-panel ul .dd-panel:nth-child(4)
{
top: -164px;
background-color:yellow !important;
}
My simple question is i always want Image & Text related to level 2 or level 3 menus to show up as top, i tried so many thing but nothing is working finally if thought of working with nth-child but i am not abel to get it right may be mixed up elements.
Based on your Image you have added in your question, I am going to give the solution. Update your CSS like below.
ul.nav > li > .dropdown.has-panel li:nth-child(3) > .dropdown.has-panel .dd-panel
{
margin-top: -90px;
background-color:green !important;
}
DEMO
I am very new to javascript and ajax/jquery and have been working on trying to get a script to open and close the drop menu on click rather that hover.
The menu in question is found on http://www.gamefriction.com/Coded/ and is the dark menu on the right side under the header. I would like it to open and close like the other menu that is further below it (it is light gray and is in the "Select Division" module).
The gray menu is part of a menu and the language menu is not.
I have a jquery import as well which can be found in the view source of the above link.
My Javascript Code:
<script type="text/javascript">
/* Language Selector */
$(function() {
$("#lang-selector li").hover(function() {
$('ul:first',this).css('display', 'block');
}, function() {
$('ul:first',this).css('display', 'none');
});
});
$(document).ready(function(){
/* Navigation */
$('.subnav-game').hide();
$('.subnav-game:eq(0)').show();
$('.preorder-type').hide();
$('.preorder-type:eq(3)').show();
});
</script>
My CSS:
#lang-selector
{
font-size: 11px;
height: 21px;
margin: 7px auto 17px auto;
width: 186px;
}
#lang-selector span
{
color: #999;
float: left;
margin: 4px 0 0 87px;
padding-right: 4px;
text-align: right;
}
#lang-selector ul
{
float: left;
list-style: none;
margin: 0;
padding: 0;
}
#lang-selector ul li a
{
padding: 3px 10px 1px 10px;
}
#lang-selector ul, #lang-selector a
{
width: 186px;
}
#lang-selector ul ul
{
display: none;
position: absolute;
}
#lang-selector ul ul li
{
border-top: 1px solid #666;
float: left;
position: relative;
}
#lang-selector a
{
background: url("http://www.gamefriction.com/Coded/images/language_bg.png") no-repeat;
color: #666;
display: block;
font-size: 10px;
height: 17px;
padding: 4px 10px 0 10px;
text-align: left;
text-decoration: none;
width: 166px;
}
#lang-selector ul ul li a
{
background: #333;
color: #999;
}
#lang-selector ul ul li a:hover
{
background: #c4262c;
color: #fff;
}
My HTML:
<div id="lang-selector">
<ul>
<li>
Choose a Language
<ul>
<li>English</li>
<li>Deutsch</li>
<li>Español</li>
<li>Français</li>
<li>Italiano</li>
</ul>
</li>
</ul>
</div>
Thanks!
$(function() {
$("#lang-selector li:first").click(function(){
$('ul:first',this).toggle();
})
});
Using toggle will require you to click to open then reclick to close
I would do something like this...
$(function() {
$("#lang-selector > li").click(function() {
$('ul:first',this).toggleClass('active');
});
});
And, then, in the CSS add this:
.active { display: block; }
<< EDIT: Removed "ul" from ".active" class for CSS rendering efficiency >>
Also make sure that the sub-nav <ul> has "display: none;" on it by default in your CSS.
This will make it so that clicking an <li> tag in #lang-selector, but not in any sub-nav <ul> tags will either open or close the sub-nav, depending on it's current state.
If you're worried about the accessibility of having "display: none" on the sub-nav by default, you can do something like this...
$(function() {
$("#lang-selector li ul").addClass("hidden");
$("#lang-selector li").click(function(e) {
e.preventDefault();
$('ul:first',$(this)).toggleClass('hidden active');
});
});
<< EDIT: Altered selectors to match example provided, turned "this" into jQuery object. >>
And then also add this to the CSS
.hidden { display: none; }
In this scenario, you have the <ul> showing by default, then when the document loads, jQuery adds the "hidden" class to all of them to hide them, then on the click of the <li> it will toggle the hidden and active classes, displaying them or hiding them.
You'll also need to remove your current "display: none" from your #lang-selector ul ul in CSS, otherwise it takes priority over the hidden / active classes.
search this $("#lang-selector li").hover and replace with
$("#lang-selector li").click
.hover, .click, .something, are all triggers, view this link:
Jquery Events
to learn more about events in Jquery!
Ps: sushil bharwani (vote it), is right, just change your .hover by the .click
if you need two functions for a click event, try .toggle
i'm using this:
$('.triggerlist').toggle(function(e) {
e.preventDefault();
$(this).find('ul').fadeIn();
},function() {
$(this).find('ul').fadeOut();
});
Which allows me to do more stuff on the 2 functions than just the .click with its 1 function.
I've built a CSS navigation menu using a sprite, very similar to the one on Apple's website. I've got it working fine, such that it changes to the right position on the image on hover and mousedown (all using CSS), but I'm having a hard time figuring out how to make a button stay highlighted once it's clicked. I have a row in my sprite for the "clicked" look, but there's no CSS that I know of to handle something that's selected. I want the buttons to turn to their "clicked" version, depending on which one has been clicked. I've explored some javascript solutions, using jQuery, but I thought there might be a better way.
The sprite I'm using is very similar to Apple's, found here.
Any help would be greatly appreciated. Thanks.
More Info:
So my menu currently looks like this in html:
<ul id="global_nav">
<li id="home_nav"></li>
<li id="systems_nav"></li>
<li id="users_nav"></li>
<li id="utilities_nav"></li>
<li id="reference_nav"></li>
<li id="metrics_nav"></li>
<li id="help_nav"></li>
<li id="info_nav"></li>
</ul>
Any my CSS is all here (sorry, it's long):
#global_nav
{
background: url("../Images/nav_bar.png");
height: 38px;
width: 979px;
padding: 0;
list-style-image: none;
list-style-position: outside;
list-style-type: none;
}
#global_nav li
{
float: left;
}
#global_nav a
{
height: 38px;
display: block;
}
#global_nav #home_nav
{
width: 118px;
}
#global_nav #home_nav a:hover
{
background: url("../Images/nav_bar.png") 0px -37px no-repeat;
}
#global_nav #home_nav a:active
{
background: url("../Images/nav_bar.png") 0px -74px no-repeat;
}
#global_nav #systems_nav
{
width: 116px;
}
#global_nav #systems_nav a:hover
{
background: url("../Images/nav_bar.png") -118px -37px no-repeat;
}
#global_nav #systems_nav a:active
{
background: url("../Images/nav_bar.png") -118px -74px no-repeat;
}
#global_nav #users_nav
{
width: 117px;
}
#global_nav #users_nav a:hover
{
background: url("../Images/nav_bar.png") -234px -37px no-repeat;
}
#global_nav #users_nav a:active
{
background: url("../Images/nav_bar.png") -234px -74px no-repeat;
}
#global_nav #utilities_nav
{
width: 117px;
}
#global_nav #utilities_nav a:hover
{
background: url("../Images/nav_bar.png") -351px -37px no-repeat;
}
#global_nav #utilities_nav a:active
{
background: url("../Images/nav_bar.png") -351px -74px no-repeat;
}
#global_nav #reference_nav
{
width: 117px;
}
#global_nav #reference_nav a:hover
{
background: url("../Images/nav_bar.png") -468px -37px no-repeat;
}
#global_nav #reference_nav a:active
{
background: url("../Images/nav_bar.png") -468px -74px no-repeat;
}
#global_nav #metrics_nav
{
width: 117px;
}
#global_nav #metrics_nav a:hover
{
background: url("../Images/nav_bar.png") -585px -37px no-repeat;
}
#global_nav #metrics_nav a:active
{
background: url("../Images/nav_bar.png") -585px -74px no-repeat;
}
#global_nav #help_nav
{
width: 117px;
}
#global_nav #help_nav a:hover
{
background: url("../Images/nav_bar.png") -702px -37px no-repeat;
}
#global_nav #help_nav a:active
{
background: url("../Images/nav_bar.png") -702px -74px no-repeat;
}
#global_nav #info_nav
{
width: 163px;
}
#global_nav #info_nav a:hover
{
background: url("../Images/nav_bar.png") -819px -37px no-repeat;
}
#global_nav #info_nav a:active
{
background: url("../Images/nav_bar.png") -819px -74px no-repeat;
}
CSS doesn't know or care what page it's on. You have to track that and output the relevant markup yourself.
Self-Answer:
To do this I essentially followed the way Apple does it on their site. I set a div with a width of the sprite, and added an unordered list within this div. Each list item represents a button along the button bar. Within each list item there is a single anchor tag that href's to the page that I want to go to when the button is clicked. In the CSS, I have a class that refers to all anchor tags under a list item under the containing div, under it's div, as such:
#globalheader #globalnav li a
{
float: left;
height: 0;
overflow: hidden;
padding-top: 36px;
width: 118px;
background-image: url("../Images/nav/nav_bar.png");
background-repeat: no-repeat;
}
This defines a background image for each of the anchor tags. Now I need to define the background position for each anchor tag, so it shows the right button. I have CSS for each anchor tag. Here's the CSS for one of them:
#globalheader #globalnav li#systems_nav a
{
background-position: -118px 0;
}
Of course I have CSS to handle the hover over the buttons (a:hover) and for the mousedown over the buttons (a:active), but my original question dealt with how to keep it on the selected look for the button when I'm on a certain page. I'll start with the CSS. If I had 6 buttons, I made six more CSS classes, each one pertaining to the container div having a certain class. That class the container has will be based on the page I'm currently on (I'll explain in a minute). Also within the definition of that CSS class, I specify which anchor tag to change the background position on. As an example, if I click the "Systems" button on the page, I will dynamically add (via javascript) a class to the container div of "systems", and this CSS will be applied as a result:
#globalheader.systems #globalnav li#systems_nav a
{
background-position: -118px -108px !important;
}
The background position is the one that covers the "clicked" look for my button. Note the .systems part of the declaration that specifies that the #globalheader div must have a class of "systems". If this is the case, it changes the background position of only a single anchor tag: you guessed it, the one right under the "systems_nav" li. I wrote one of these classes for each of the buttons in the button bar. The second trick was writing the javascript to handle dynamically adding the class to the div depending on what page I was on. To do this, I put a hidden div on each page that looked something like this:
<div id="page_section" title="systems" style="display: none;"></div>
It's not displayed, has a generic id that each of these divs will have on each page on my site, and has a title specific to the page I'm on. In my javascript file, I wrote this (it uses jquery):
var $globalheader = $('#globalheader'); // container div to add the class to
var $page_section = $('#page_section'); // div whose title is the current page
$globalheader.addClass($page_section.attr('title'));
Voila. "systems" gets added as the class name to the "globalheader" div, and the correct CSS class gets applied, making only the Systems button look clicked.
This took a little work by looking at Apple's website, but this is how they do it, and I trust them. It worked for me.
Hope it helps anyone else having the same problem I was.
Do you use a server-side programming/scripting language like PHP/ASP/JSP? If so, then you can just render a CSS class conditionally. Here's a PHP example (you can get requested page in PHP by one of the $_SERVER variables):
<a href="somepage"<?php echo ($currentpage == 'somepage' ? ' class="active"' : ''); ?>>somepage</a>
If you don't use a server side language, then the only resort is JS/jQuery. Do something like following during onload (you can get requested page in JS by parsing the window.location):
$('a[href="' + currentpage + '"]').addClass('active');
The CSS class a.active should obviously shift the background-position so that it becomes "active".