I have this menu
<ul id="menu" class="clearfix">
<li>
Product 1
</li>
<li>
Product 2
</li>
<li>
Product 3
</li>
<li class="last">
Product 4
</li>
</ul>
I want to make this effect. when you enter the page the text color of the menu items are white. If you click on one item it becomes active (keeping the white color text) and all the other items change it's color to gray, also when you hover over one the affected items are all the others.
I have tried with the .addClass but I have only managed to add the active class to the current item, but not change the others that aren´t active after the first click.
Anyone know the best jquery approach to this?
$("#menu li").hover(function() {
$(this).removeClass('grey').siblings().addClass('grey');
}, function() {
$(this).addClass('grey').siblings('.active').removeClass('grey');
//
}).on('click', function() {
$(this).removeClass('grey').addClass('active').siblings().addClass('grey').removeClass('active')
});
http://jsfiddle.net/y7Cn5/
Perhaps something like this: Updated, with hover functionality
jsFiddle
$("#menu > li").on("click", function(e) {
e.stopPropagation();
$(".active").removeClass("active");
$(this).removeClass("non-active").addClass("active").siblings().addClass("non-active");
})
.hover(function(e) {
$(".non-hover").removeClass("non-hover");
$(this).addClass("hover").siblings().addClass("non-hover");
}, function(e) {
$(".hover, .non-hover").removeClass("hover non-hover");
})
and if this doesn't answer the question, then the question is not understood and needs some rewording, this is everything asked about in the question
Here you go (siblings) selects all OTHER items in the same node
$("#menu li").click(function(){
$(this).addClass("active").css("color","white")
$(this).siblings().css("color","gray")
})
Try
$("#menu > li").hover( function( ) {
$(this).removeClass("hovered").siblings().addClass("hovered");
}, function( ) {
$(this).addClass("hovered");
});
$("#menu > li").click( function( ) {
$(this).addClass("active").siblings().removeClass("active");
});
Related
I have this code
<script>
$("li").hover(
function () {
$(this).addClass('active');
},
function () {
$(this).removeClass('active');
}
);
</script>
In order to add class active to my li in a menu.
<ul class="list-first-level">
<div about="" typeof="" class="ds-1col entity entity-paragraphs-item paragraphs-item-modulo-de-enlaces-item view-mode-modulo_de_enlaces_01_d clearfix">
<li id="elm" class="active always">
Undergraduate programmes
<ul>
<li>
Law
</li>
</ul>
</li>
</div>
</ul>
I need to not remove the active class after Im not hover on the element.
Just use this:
$("li").hover(function(){
$(this).addClass("active");
});
Although, you will end up with many active LI and does not provide a good UX.
When you hover over an element, remove the 'active' class from all li elements then add it back to the current element. This still means that if the user moves away from the last, hovered element - that element will remain in an 'active' state.
<script type="text/javascript">
$("li").hover(
function () {
$("li").removeClass('active');
$(this).addClass('active');
}
);
</script>
I have searched a lot for adding active class to the parent menu using javascript.
I found many more examples but not a single one is working for me, below is my code
HTML
<div id="menu1" class="hmenu">
<ul>
<li>Item1
<ul>
<li>SubItem1
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
<li>SubItem2 </li>
<li>SubItem3
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
</ul>
</li>
<li>Item2</li>
<li>Item3
<ul>
<li>SubItem1
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
</ul>
</li>
</ul>
<br style="clear: left" />
</div>
My requirement is when i click on SubItem1 then both Item1 and SubItem1 should be active.
And when i click on SubSubItem1 then SubSubItem1 ,SubItem1 and Item1 should be active.
Means when click on any link then its all parent link and the same link should be active.
I have tried with this javascript code :
$(document).ready(function () {
$('.hmenu ul li ul').find('li').click(function () {
//removing the previous selected menu state
$('.hmenu').find('li.active').removeClass('active');
//adding the state for this parent menu
$(this).parents('li').addClass('active');
});
});
Actually i don't have any experience with javascript coding and unable to figure out the problem in my code.
Can anyone suggest me for the same.
The issue comes from .find('li').click().
As you use nestsed <li>, this will cause the event to be fired two times when you click on a child <li>. This causes problems. Can not you add the click() to <a> elements?
$(document).ready(function () {
$('.hmenu a').click(function () {
//removing the previous selected menu state
$('.hmenu').find('li.active').removeClass('active');
//adding the state for this parent menu
$(this).parents("li").addClass('active');
});
});
It works just fine: https://jsfiddle.net/6put8tdx/
Note that your page will be bumped to the top while clicking to a tab because of # anchor. If you want to prevent this, you may pass the event to the function .click(function (event) {...} and add event.preventDefault inside.
If you need the click target to be the LI element (as opposed to Delgan's answer)
you can use .not() over the targeted LI's parents to prevent messing with the bubbling event targets:
$(document).ready(function () {
$('.hmenu').find('li').click(function(event) {
event.preventDefault(); // Prevent page jumps due to anchors
var $par = $(event.target).parents("li"); // get list of parents
$(".hmenu .active").not( $par ).removeClass("active"); // not them
$(this).addClass('active'); // let the event propagation do the work
});
});
$(document).ready(function () {
$('.hmenu').find('li').click(function(event) {
event.preventDefault();
var $par = $(event.target).parents("li");
$(".hmenu .active").not($par).removeClass("active");
$(this).addClass('active');
});
});
.active > a{
background: gold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu1" class="hmenu">
<ul>
<li>Item1
<ul>
<li>SubItem1
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
<li>SubItem2 </li>
<li>SubItem3
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
</ul>
</li>
<li>Item2</li>
<li>Item3
<ul>
<li>SubItem1
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
</ul>
</li>
</ul>
<br style="clear: left" />
</div>
To better understand the above
The following example works out-of-the-box, and the clicked one and all it's LI parents get the "active" class.
Why? Cause the event target is li, means any li of .hmenu - so that click is attached to any of them, and clicking the subsub LI the event will propagate to the LI parents - triggering the same click behavior (this add class)!
$(".hmenu").on("click", "li", function(){
$(this).addClass("active"); // Wow! Event propagation rulez!!
});
But we need to remove existing .active and here it gets messy...
$(".hmenu").on("click", "li", function(){
$(".active").removeClass("active"); // triggered on every event bubble :(
$(this).addClass("active"); // leaving only the main parent with active class
});
That's caused by the concurrency that happens while the event bubbles and triggers the same actions for the parent elements.
One way to prevent that concurrency would be using a setTimeout of 1ms:
$(".hmenu").on("click", "li", function(){
$(".active").removeClass("active");
setTimeout(function(){ // Let the previous finish the bubbling mess
$(this).addClass("active"); // Yey! all fine! Every LI has the active class
}, 1);
});
But here the timeout of 1ms can lead to visual "blinking" issues.
Try this:
$(function () {
$("li a")
.on("click", function () {
$(this).toggleClass("active");
$(this).closest("ul").parent().children("li a").toggleClass("active")
.parent().parent().parent().children("li a").toggleClass("active");
});
});
fiddle
Traverse from the clicked element. And use toggleClass() to avoid the mundane checking if hasclass removeClass ...
on my Demo, I add and remove the class Selected. If I click through the links and then click again the
OPEN FORM the toggleClass doesn't work on a first click. why? what am I missing?
Basically by clicking OPEN FORM I should addClass('selected') and toggleClass('open') .
Please see my Demo, and click the links.
http://jsfiddle.net/y8oL13Ld/
my js:
$('.cta a').on('click', function (e) {
e.preventDefault();
$('.cta a').removeClass('selected');
$(this).addClass('selected');
if ($('.Contact-form.selected').is(':visible')) {
$('.cloned-contactform').addClass('open');
} else {
$('.cloned-contactform').removeClass('open');
}
$('.Contact-form.selected').bind('click', function () {
$('.cloned-contactform').toggleClass('open');
});
});
html:
<ul class="cta">
<li>OPEN FORM</li>
<li>LINK</li>
<li>LINK</li>
</ul>
<div class="cloned-contactform">
<div class="contactform"></div>
</div>
are you look for soemthing like this?: http://jsfiddle.net/y8oL13Ld/1/
$('.Contact-form').on('click', function() {
$('.cta a').removeClass('selected');
$(this).addClass('selected');
if ($('.cloned-contactform').is(':visible')) {
$('.cloned-contactform').removeClass('open');
$('.cloned-contactform').hide();
}
else {
$('.cloned-contactform').addClass('open');
$('.cloned-contactform').show();
}
});
explanation: the OP js is a little convoluted in the logic. although i'm not exactly sure exactly the functionality of what the OP wants, i ripped all unnecessary js and fulfilled the requirements that:
clicking OPEN FORUM adds the class selected to the anchor (and removes selected from other links if they have class selected)
the div cloned-contactform's class open gets toggled
the div cloned-contactform's visibility toggles
EDIT: due to the refined definition of requirements i updated the jsfiddle: http://jsfiddle.net/y8oL13Ld/2/
the following jquery handles the fact that if the other links are clicked, it closes the div cloned-contactform and are selected.
$('.Globe, .Search').on('click', function() {
$('.cta a').removeClass('selected');
$(this).addClass('selected');
$('.cloned-contactform').removeClass('open');
$('.cloned-contactform').hide();
});
FINAL EDIT: hopefully lol, due to scope change. http://jsfiddle.net/y8oL13Ld/4/
$('.cta a').on('click', function(){
// if clicked contact link
if ($(this).hasClass('contact')) {
// if already selected
if ($(this).hasClass('selected')) {
// toggle
$('.contact-div').removeClass('open');
$(this).removeClass('selected');
}
// if not already selected
else {
// remove selected and open classes from all others
$('.cta a').removeClass('selected');
$('.section').removeClass('open');
// apply selected and open classes to this
$('.contact-div').addClass('open');
$(this).addClass('selected');
}
}
});
and i switched the html structure a little:
<div class="contact-div section">contact div</div>
<div class="global-div section" style="background:gray;">global div</div>
<div class="search-div section" style="background:lightgray;"> search div</div>
Kinda guessing here, but it looks like you're making a nav and clicking a link in it shows a certain div. If that's what you're trying to achieve maybe some refactoring advice could be this:
Have a div for each of your sections
<div class="section contact-form">Form Stuff</div>
<div class="section globe">Globe Stuff</div>
<div class="section search">Search Stuff</div>
Then your links could be like:
<li>OPEN FORM</li>
<li>LINK</li>
<li>LINK</li>
Then your javascript code is ambiguous to which link you clicked:
$('a').click(function(){
// Grab the value of data-section
var selected = $(this).data('section')
$('.section').hide()
// Show the corresponding div
$("'."+ selected + "'").show()
});
http://jsfiddle.net/4brfejw5/
I'm working with the off-canvas script from Foundation and it isn't working out of the box (of course) when I try to use the submenu options. I realized it wasn't adding a class (move-right) to the ul's of the li's in the off-canvas navigation. So I wrote a script to add that class which can be found here:
jQuery(document).ready(function() {
jQuery('ul.off-canvas-list li a').click(function() {
jQuery('ul.off-canvas-list li ul.left-submenu').addClass('move-right');
});
});
And here is how my HTML is structured:
<ul class="off-canvas-list">
<li class="has-submenu">Name 1
<ul class="left-submenu">
<li class="back">Back</li>
<li><a href="#"></li>
<li><a href="#"></li>
</ul>
</li>
<li class="has-submenu">Name 2
<ul class="left-submenu">
<li class="back">Back</li>
<li><a href="#"></li>
<li><a href="#"></li>
</ul>
</li>
<li class="has-submenu">Name 3
<ul class="left-submenu">
<li class="back">Back</li>
<li><a href="#"></li>
<li><a href="#"></li>
</ul>
</li>
...etc
</ul>
My problem is that my script is adding the class to ALL ul.left-submenu's instead of just the one directly under the li that I click on. I can't figure out how to add the class 'move-right' to only the 'ul.left-submenu' child of the parents li that I clicked on and remove the 'move-right' class from the other 'ul.left-submenu'
I thought maybe using the sibling() selector, but I wasn't quite sure how to implement that into my script. Any and all help is greatly appreciated.
Another issue has arose and that is being able to close the opened "ul.left-submenu" by clicking on the "Back" which comes before the other li's in each ul.left-submenu. I updated the HTML above to include the "" and also have provided the script below that I tried using that hasn't worked.
jQuery('li.back').on('click', function() {
console.log('close submenu');
jQuery('ul.left-submenu').removeClass('move-right');
});
The target element is the grandparent of the clicked element so you can use the closest method:
$('ul.off-canvas-list li a').click(function() {
$('.move-right').removeClass('move-right');
$(this).closest('ul.left-submenu').addClass('move-right');
});
you can add it directly to the clicked element by using this
jQuery(document).ready(function() {
jQuery('.left-submenu li a').click(function() {
jQuery('.left-submenu').removeClass('move-right'); // remove class move-right from every elements with class left-submenu
jQuery(this).parents('.left-submenu').addClass('move-right'); // add class move-right to the parent with class left-submenu of current element
});
});
Edit:
if in your updated code, you want to click only by a right after .has-submenu, you need this probably, so it didn't trigger on click for a inside .left-submenu
jQuery(document).ready(function() {
jQuery('.has-submenu > a').click(function() {
jQuery('.left-submenu').removeClass('move-right'); // remove class move-right from every elements with class left-submenu
jQuery(this).children('.left-submenu').addClass('move-right'); // add class move-right to the children with class left-submenu of current element
});
});
sorry for my mistakes not looking again for the code before posting it, because ul.left-submenu is in the same position with a and not it's children, you need to use .siblings to get ul.left-submenu, so change the code to this
jQuery(document).ready(function() {
jQuery('.has-submenu > a').click(function() {
jQuery('.left-submenu').removeClass('move-right');
jQuery(this).siblings('.left-submenu').addClass('move-right');
});
});
here's the working Example in Fiddle
Ok, so you want to add a class move-right to the ul.left-submenu that is directly under the has-submenu li that you clicked, right?
So:
$(document).ready(function() {
//Trigger the click only on the li's has-submenu
$('li.has-submenu').on('click', function() {
//Remove the class from other ul, if there's any
$('ul.left-submenu').removeClass('move-right');
//Finds the direct ul child using the '>' selector, and adds the class.
$(this).find('> ul.left-submenu').addClass('move-right');
});
});
The way you have your selector it targets all the ul.left-submenu elements you have, another way to target just the element clicked would be like this:
$('.off-canvas-list').on('click', 'ul.off-canvas-list li a', function (){
$('.move-right').removeClass('move-right');
$(event.target).closest('ul.left-submenu').addClass('move-right');
});
Your selector is too broad. If what you want to do is to add move-right to left-submenu when you click has-submenu, that's what you need to do:
$('.has-submenu').click(function() {
$(this).find($('.left-submenu')).addClass('move-right');
});
Fiddle: http://jsfiddle.net/x9zcav0p/
If you need to reset move-right, do this:
$('.has-submenu').click(function() {
$('.move-right').removeClass('move-right');
$(this).find($('.left-submenu')).addClass('move-right');
});
Fiddle: http://jsfiddle.net/x9zcav0p/1/
Updated markup:
For your updated markup, you can target the next() element after the anchor tag:
$('.has-submenu > a').on('click', function() {
$('.move-right').removeClass('move-right');
$(this).next().addClass('move-right');
});
Fiddle: http://jsfiddle.net/x9zcav0p/2/
Here I have a list, what I want to do is I need to change the list ( li ) background color to different one after click on a specific list item. the thing is once it click on the link page will be redirected and refresh. please can me suggest a solution for to get this done?
<div id="main-menu">
<ul id="main-menu-list">
<li id="menu-home">Home</li>
<li id="menu-profile">My Profile</li>
<li id="menu-dashboard">My Dashboard</li>
<li id="menu-search">Search</li>
</ul>
</div>
what i did for this :
Java Script :
var make_button_active = function()
{
//Get item siblings
var siblings =($(this).siblings());
//Remove active class on all buttons
siblings.each(function (index)
{
$(this).removeClass('active');
}
)
//Add the clicked button class
$(this).addClass('active');
}
//Attach events to menu
$(document).ready(
function()
{
$("#main-menu li").click(make_button_active);
}
)
CSS :
#main-menu-list li.active {
background: #0040FF;
}
It's a little difficult to tell exactly what you want to do, but here's some quick and dirty (and untested) code:
/// when we click on an `a` tag inside the `#main-menu-list`...
$('#main-menu-list').on('click', 'a', function(e) {
// stop the link from firing
e.preventDefault();
e.stopPropagation();
// change the list item's background to green
$(this).closest('li').addClass('myClassName').css('background-color', 'green');
// do anything else, e.g. load in pages via ajax...
});
You could use CSS to apply the green background color, instead of jQuery:
.myClassName { background-color: green; }
This will stop the page from navigating, and I don't know if that's your intention. If you want to check the currently-loaded page against the menu to find the current item, you could do this (on page load) instead:
var currentPage = window.location.pathname;
$('#main-menu-list').find('a[href^="' + currentPage + '"]').closest('li').addClass('active');
EDIT:
Your amended Javascript code can be simplified to the following:
$('#main-menu li').on('click', 'a', function (e) {
e.preventDefault();
e.stopPropagation();
// only do the following if the clicked link isn't already active
if(!$(this).closest('li').hasClass('active')) {
$(this).closest('ul').find('.active').removeClass('active');
$(this).closest('li').addClass('active');
// load in your content via ajax, etc.
}
});
JSFiddle example
For each page you can add a class to the current list item that has "where the user is"..
CSS:
.selectedItem{
background-color: orange;//whatever color your want for the selected tab..
}
Then for each of your pages,
say you're in Dashboard.html
your menu code will look like:
<div id="main-menu">
<ul id="main-menu-list">
<li id="menu-home">Home</li>
<li id="menu-profile">My Profile</li>
<li id="menu-dashboard" class="selectedItem">My Dashboard</li>
<li id="menu-search">Search</li>
</ul>
</div>
in profile.html:
<div id="main-menu">
<ul id="main-menu-list">
<li id="menu-home">Home</li>
<li id="menu-profile" class="selectedItem">My Profile</li>
<li id="menu-dashboard">My Dashboard</li>
<li id="menu-search">Search</li>
</ul>
</div>
and so on..
You need to change the background color when the document is loaded (i.e. in document.ready).
Then you need a mechanism to connect the currently loaded page to one of your list items.
$(document).ready(function(){
//get the url from the current location or in some other way that suits your solution
//perhaps use window.location.pathname
var moduleId = "dashboard" // hardcoded to dashboard to make the point :);
$("#menu-"+moduleId).css("background-color", "#ccc");
});
http://jsfiddle.net/9JaVn/1/