I'm trying to build a simple jQuery slide down navigation but I'm having a bit of a issue with toggle in on and off the navigation.
I have navigation as follows.
<ul id="nav">
<li>home</li>
<li class="parent">Clothing
<ul>
<li>child</li>
<li>child</li>
<li>child</li>
</ul>
</li>
<li class="parent">shoes
<ul>
<li>child</li>
<li>child</li>
<li>child
<ul>
<li>child child</li>
</ul>
</li>
</ul>
</li>
with the following jquery
var $j = jQuery.noConflict();
$j(document).ready(function() {
$j('#nav').children('.parent').click(function(e){
e.preventDefault();
$this = $j(this);
$j('#nav').children('.parent').children('ul').stop().slideUp('slow', function(){
$this.children('ul').stop().slideToggle('slow');
});
});
});
Now when i click the Sub navigation slides out, clicking again does nothing, and i need it to slide back up. If i click another one what I need to happen is have the expanded nav (if any) slide back up, and then the new one slide down after, but it's just not wanting to work correctly for me! It's buggy and both display at once, and sometimes don't show.
See this...
var $j = jQuery.noConflict();
$j(document).ready(function() {
$j('#nav > .parent').on('click', function(e){
e.preventDefault();
$j('#nav > .parent').children().stop().slideUp('slow');
$j(this).children().stop().slideToggle('slow');
});
});
See this jSfiddle example
Related
I have a main menu.
The sub-menu opens when the link of any of the PARENT <li> that have children is clicked.
At this point, a class moves-out is added to the main menu and a CSS transition is started.
After the transition ends, the sub-menu is displayed.
The sub-menu contains the clicked <li> (if clicked again will take us back to the main menu) and it's children.
Here, my goal is to disable the click event on the parent <li> for 1 second,
then after this 1 second give it back the ability to be clicked so we can go back to the main menu.
An example of the navigation would be :
<ul class="main-nav">
<li>Home</li>
<li>Blog</li>
<li>About</li>
<li>Contact</li>
<li>
<span>PARENT</span>
<ul>
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
And so on...
</ul>
</li>
</ul> <!-- .main-nav -->
The only way that worked for me was to hide/show the PARENT when the main menu has the moves-out class added to it like so :
$('.subnav-trigger').on('click', function(event) {
event.preventDefault();
if ($('.main-nav').hasClass('moves-out')) {
var $this = $(this);
$this.hide();
setTimeout(function(){
$this.show();
}, 1000);
}
}
I've tried A LOT off things, this is the only one that is near to my goal.
Instead off $this.hide(), $this.off('click') is working
but inside the setTimeout what ever I do to regain the click doesn't work.
Any help would be greatly appreciated.
NOTE : I want this to prevent fast click/re-click. Don't forget the transition ;)
Thanks again in advance for any help.
SYA :)
Try setting pointer-events on the li tag and resetting it after 1 second.
$('.subnav-trigger').on('click', function(event) {
event.preventDefault();
var $this = $(this);
$this.parent().css("pointer-events","none");
if ($('.main-nav').hasClass('moves-out')) {
$this.hide();
setTimeout(function(){
$this.show();
$this.parent().css("pointer-events","auto");
}, 1000);
}
});
Here's a way using a recursive function that enabled the click handler, disables it on click, enables the transitionend event, adds your class that enables the transition, then re-enables the function. Enabled a 3s transition to slow it down for the example.
var $lis = $('li'),
clicker = function() {
$lis.on('click', function() {
$lis.off('click');
$(this).on('transitionend', function() {
clicker();
}).addClass('color');
});
}
clicker();
li {
transition: background 3s;
}
li.color {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="main-nav">
<li>Home</li>
<li>Blog</li>
<li>About</li>
<li>Contact</li>
</ul>
More like a debounce problem, you might want to take a look at it if you have not used it before, it will help a lot in design you code.
For the following example, I added moves-out to ul for testing, you can check the console.log to see the result. To use in your app don't forgot to remove it (moves-out) from the <ul...>
<ul class="main-nav moves-out">
function debounce() {
if ($('.main-nav').hasClass('moves-out')) {
console.log("Clicked - click event Disabled..");
$(this).off('click');
setTimeout(function() {
$(".subnav-trigger").on('click', debounce);
console.log("click event enabled!");
}.bind(this), 1000);
}
};
$(".subnav-trigger").on('click', debounce);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul class="main-nav moves-out">
<li>Home</li>
<li>Blog</li>
<li>About</li>
<li>Contact</li>
<li>
<span>PARENT</span>
<ul>
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
And so on...
</ul>
</li>
</ul>
<!-- .main-nav -->
The submenu on each menu item slides underneath the main menu item instead of sliding out whenever I click on a menu item, which is what it's supposed to do. Problem is the site itself automatically scrolls up. Its as if the main menu items have a link to them that is anchored to the top of the site. I click on them, the submenu slide out, but the site itself scrolls up everytime.
How to make the code cross-browser compatible?
The javascript code:
<script type="text/javascript">
<!--//--><![CDATA[//><!--
startList = function() {
if (document.getElementById) {
navRoot = document.getElementById("nav");
for (i=0; i<navRoot.childNodes.length; i++) {
node = navRoot.childNodes[i];
if (node.nodeName=="LI") {
node.onclick=function() {
this.className = (this.className == "on") ? "off" : "on";
}
}
}
}
}
window.onload=startList;
//--><!]]>
</script>
The html code:
<ul id="nav">
<li>Home </li>
<li>About >
<ul>
<li>History </li>
<li>Team </li>
<li>Offices </li>
</ul>
</li>
<li>Services >
<ul>
<li>Web Design </li>
<li>Internet Marketing </li>
<li>Hosting </li>
<li>Domain Names </li>
<li>Broadband </li>
</ul>
</li>
<li>Contact Us >
<ul>
<li>United Kingdom</li>
<li>France</li>
<li>USA</li>
<li>Australia</li>
</ul>
</li>
</ul>
Based off of this menu: http://www.pmob.co.uk/temp/drop-down-expand.htm#
The reason is because you have "#" in your hrefs...this is telling the browser to return to the top. You need to return false on your onclick so that the default behavior (navigating to the href) doesn't happen on the items that are not truly "links".
You can always add e.preventDefault() to the event listener to remove all hyperlink-effects after clicked.
Using preventDefault is usually more recommended.
http://jsfiddle.net/Z8Uvj/
$("a").click(function(e){
//your stuff
e.preventDefault();
});
I am having some issues figure out how i can just remove a class ="active" from a just one of my lists.
I have a navigation bar:
<div class="container">
<ul class="nav">
<li class="active">Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
I also have a menu within Home:
<div class="container_2">
<ul>
<li class="left-main-list active">Subject 1</li>
<ul class="list-in-list">
<li>Sub subject 1</li>
<li>Sub subject 2</li>
</ul>
<li class="left-main-list>Subject 2</li>
<li class="left-main-list>Subject 3</li>
</ul>
</div>
While i browse my menu on the home page, i want to change the the active list items class to active when clicked, so i now have this jQuery code:
$(document).ready(function() {
$('li').click(function() {
$('li').removeClass('active');
$(this).addClass('active');
});
});
This works for my menu, the class change to the current one, but it also delete my navigation bars class, which i don't want. :)
I have tried something like:
$(document).ready(function() {
$('.left-main-list').click(function() {
$('.left-main-list li').removeClass('active');
$(this).addClass('active');
});
});
I've tried '.left-main-list li' & 'li.left-main-list' without any success.
Greatful for answer to this question, and i hope my question (this time) is more accurate than my previous ones. :)
/Bill
ps: Can a sub subject AND a main subject be active at the same time, and that sub subject's class of active, be removed if you for example click another sub subject, but the main item still have it's class of active?
While i browse my menu on the home page, i want to change the the
active list items class to active when clicked
You could just target the lis within the relevant div, similar to this:
$(document).ready(function() {
var $listItems = $('div.container_2 li');
$listItems.click(function() {
$listItems.removeClass('active');
$(this).addClass('active');
});
});
DEMO - target lis within .container_2 only
Can a sub subject AND a main subject be active at the same time, and
that sub subject's class of active, be removed if you for example
click another sub subject, but the main item still have it's class of
active?
Still targeting the container you could use jQuery's parent(), similar to this:
$(document).ready(function () {
$('div.container_2 li').click(function () {
var $this = $(this);
var $children = $this.parent().find('li');
$children.removeClass('active');
$this.addClass('active');
});
});
DEMO - Using parent() to allow active menu and sub-menu but not when main menu changes
I looked at the possibility of making this more dynamic to add activation of items going up the chain when switching between sub menus located within different main menu elements.
Fixing the HTML of the nested uls whereby your nested uls are inside lis instead of just inside the upper ul you can do a fully dynamic implementation.
Assume your HTML like this:
<div class="container">
<ul class="nav">
<li class="active">Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
<div class="container_2">
<ul>
<li class="left-main-list active">Subject 1
</li>
<li>
<ul class="list-in-list">
<li>Sub subject 1
</li>
<li>Sub subject 2
</li>
<li>
<ul class="list-in-list">
<li>Sub subject 1
</li>
<li>Sub subject 2
</li>
</ul>
</li>
</ul>
</li>
<li class="left-main-list">Subject 2
</li>
<li class="left-main-list">Subject 3
</li>
</ul>
</div>
Now, using the following script, you can also make parents of any sub menu items active when changing from a sub menu to another which is within another main menu item, similar to this:
$(document).ready(function () {
$('div.container_2 li>a').click(function () {
var $this = $(this);
var $relatedElements = $this.parents('ul').find('li');
if($this.hasClass('active')){
return;
}
$relatedElements.removeClass('active');
$this.parent('li').addClass('active');
var $parents = $this.parents('li');
$parents.each(function(){
$(this).not($this.parent()).prev().addClass('active');
});
});
});
DEMO - Chain-like activation
I think this should have all possible examples to get you started from here.
Hope this helps.
Try this:
$("li").click(function() {
$(this.parentNode).children("li").removeClass("active");
$(this).addClass("active");
});
This will affect only the siblings of the element you click on.
$('.left-main-list').click(function() {
$('.left-main-list').removeClass('active');
$(this).addClass('active');
});
I think what you're looking for is this:
$(document).ready(function() {
$('li').click(function() {
$('li.left-main-list').removeClass('active');
$(this).addClass('active');
});
});
How about
$('li').on ('click', function (){
$(this).addClass ('active').siblings ('li').removeClass ('active');
})
On this page http://kimcolemanprojects.com/ I need to have a drop down menu that opens on click and closes again on click of same anchor. Like it works on this site http://angela-moore.co.uk/
This is my html for the menu so far:
<div class="left" id="nav">
<ul id="menu">
<li id="light">
Lighting + Video
<ul style="display: none;">
<li>Django Django</li>
<li>Suntrap</li>
</ul>
</li>
<li id="photo">
Photograms
</li>
<li id="about">
<a class="active" href="about.html">About</a>
</li></ul>
</div><!--end nav-->
As you can see I only need it to work within one list item. I need help writing the Javascript for this.
So when on index page the user can see three links lighting + video, Photograms, About. When user clicks on lighting + video a sub menu opens beneath with more links. Then it will close again if the user clicks again on lighting + video. The same can happen with each of the initial three links on the index page.
Quite Simple..
<script src="jquery.js"></script>
<div id="navigation">
<p>Menu</p>
<ul id="menu">
<li>Menu 1<ul>
<li>lol</li><li>lol2</li><li>lol</li><li>lol2</li>
</ul></li>
<li>Menu 2<ul>
<li>lol</li><li>lol2</li><li>lol</li><li>lol2</li>
</ul></li>
<li>Menu 3<ul>
<li>lol</li><li>lol2</li><li>lol</li><li>lol2</li>
</ul></li>
<li>Menu 4<ul>
<li>lol</li><li>lol2</li><li>lol</li><li>lol2</li>
</ul></li>
This will be your HTML container etc, under this you will need your javascript to control that hiding and changing!! You can add some styling also if you feel artistic!
<script>
var showMenuText = $('#toggle').text();
var hideMenuText = 'Close';
$('#navigation ul').hide();
$('#navigation ul a.active+ul').show();
hideMenu = function() {
$('#navigation ul#menu').hide();
$('#navigation').removeClass('open');
$('#toggle').text(showMenuText);
}
$('#toggle').click(function(event){
event.stopPropagation(); event.preventDefault();
$('#navigation ul#menu').toggle();
$('#navigation').toggleClass('open');
var toggleText = $('#toggle').text();
(toggleText == showMenuText) ? $(this).text(hideMenuText) : $(this).text(showMenuText);
});
$('ul#menu > li > a').click(function(event){
$this = $(this);
if( $this.hasClass('page') ) parent.location = $this.attr('href');
if( $this.hasClass('home') ) { parent.location = '/'; }
event.preventDefault(); event.stopPropagation();
if( $this.hasClass('active') ) var justclosed = true;
$('a.active').removeClass('active').next('ul').hide();
if(!justclosed) $this.addClass('active').next('ul').show();
});
</script>
This is a simple HTML Example and you can execute it how you like.
I'm looking for a solution, it must work in IE also, that I can have the content hidden and then when you click one of the menu items it shows the content. However, the content doesn't hide until a user clicks on the next link...
Please check this link
http://jsfiddle.net/varada/YLX9x/
you can use jquery hide() and show() functions for that.
Let the id of div that is to be hidden be hidden_div, let menu item be menu_item, next button be next,
Import the jquery.js
and write the ready function as below..
$(document).ready(function() {
$('#menu_item').click(function() {
$('#hidden_div').show();
});
$('#next').click(function() {
$('#hidden_div').hide();
});
});
or if you mean the content be visible till he click the next link on the menu item, add a class name say, menu_class to the menu items and write the code
$('.menu_class').click(function() {
$('#hidden_div').hide();
});
instead of $('#next').click(function()
if you have a menu like
<ul>
<li class='menu_class'>item 1</li>
<li id='menu_item' >item 2</li>
<li class='menu_class'>item 3</li>
</ul>
and the div
<div id='hidde_div' style='display:none'>
content
</div>
then if you click item 2 the div will get displayed. and if you click item 1 or item 3 it will get hidden. make sure you are using the code $('.menu_class').click(function() {
html:
<li class="main">Web
<ul>
<li>Designing</li>
<li>Development</li>
</ul>
</li>
<li class="main">IT
<ul>
<li>Sales & Service</li>
<li>CCTV</li>
<li>DVR</li>
</ul>
</li>
<li class="main">ITES
<ul>
<li>BPO</li>
<li>Online Portal</li>
<li>Online Marketing</li>
</ul>
</li>
js:
$(document).ready(function(){
$('li ul:not(:first)').hide();
$('ul li').click(function(){
$(this).closest('.main').next().find('ul').show();
$(this).closest('ul').hide();
});
});
http://jsfiddle.net/7QheB/