In my horizontal menu / submenu I'm coding I have a class="hidden" on the subMenuBarWrapper ul that I'd like to remove on the active ul on mouseenter.
Currently I have .toggle which is okay but I'd prefer the "class" way instead. Could someone help me with a possible solution? Thanks.
HTML
<div class="subMenuBarWrapper">
<ul data-parentid="1" class="hidden">
<li class="">
<a href="etc....</a>
</li>
</ul>
</div>
JS
$('.nav_options li a').on('mouseenter', function () {
var targetmatch = $(this).attr('data-submenunum');
$('.subMenuBarWrapper ul').each(function () {
$(this).toggle(targetmatch.length < 1 || $(this).attr('data-parentid').indexOf(targetmatch) > -1);
});
});
You can use your exact same logic and use toggleClass():
$(this).toggleClass('hidden', targetmatch.length < 1 || $(this).data('parentid').indexOf(targetmatch) > -1);
The first argument is the class name to use, and the second is a boolean to determine whether this should be added to or removed from the element in question. Also, note the use of .data() over .attr('data-...')
Related
I have a page with a list of menu items consisting of internal anchors. I'm trying to add an .active class to the selected item. It seems to work on load but when clicking a new item in that same page it doesn't.
When clicking a new menu item, I would like to remove all other active classes and add this class to the clicked item.
Sounds pretty simple, but I can't make it work.
I created this Fiddle, but it doesn't show the issue correctly, since I can't add hashes to the url.
However, maybe someone can point me in the right direction.
JS:
function setActiveLinks() {
var current = location.pathname;
$('.bs-docs-sidenav li a').each(function() {
var $this = $(this);
// Get hash value
var $hash = location.href.substr(location.href.indexOf('#') + 1);
if ($this.attr('href') == '#' + $hash) {
$this.parent().addClass('active');
}
})
}
setActiveLinks();
$('#leftmenu li a').click(function() {
$('#leftmenu li').removeClass('active');
setActiveLinks();
});
HTML:
<ul class="nav bs-docs-sidenav">
<li>
Download
</li>
<li class="active">
What's included
<ul class="nav">
<li class="active">Precompiled</li>
<li>Source code</li>
</ul>
</li>
<li>
Compiling CSS and JavaScript
<ul class="nav">
<li>Installing Grunt</li>
<li>Available Grunt commands</li>
<li>Troubleshooting</li>
</ul>
</li>
</ul>
Thanks. :-)
You have wrong selector to bind click event on anchor element. also you don't need to call setActiveLinks() function(which sets class based on href) here.
You can use context of clicked anchor element to traverse to parent li and add class active in it:
var $navLIs = $('.nav li')
$navLIs.find('a').click(function() {
$navLIs.removeClass('active');
$(this).parent().addClass('active');
});
Working Demo
I have a set of links :
<div id="links">
<a>A</a>
<a>B</a>
<a>C</a>
…
</div>
And in the same page also I have a set of tabs:
<ul id="target">
<li>#1</li>
<li>#2</li>
<li>#3</li>
….
</ul>
how can I make the first < a>(A) scroll to the first < li>(#1) and the second < a>(B) scroll to the second < li>(#2) and the third < a>(C) scroll to the third < li>(#3) and so on …….
Note:
The number of links and its targets not fixed It's dynamic, so I can't add id's to every item.
Add IDs to your list elements, and link them up.
<div id="links">
A
B
C
<ul id="target">
<li id="link_1">#1</li>
<li id="link_2">#2</li>
<li id="link_3">#3</li>
</ul>
Granted, this solution does not animate the scrolling, so you jump to the location in the document. Adding a jQuery plugin that adds scrolling animation should work without changing the code, though.
With jQuery, you could do something like this:
$('#links a').on('click', function () {
//get the index of clicked a
var index = $(this).index();
//scroll to the li of equal index
$('html, body').animate({
scrollTop: $($("#target li").eq(index)).offset().top
}, 500);
});
Here's a working example:
https://jsbin.com/ruwacejifi/edit?html,js,output
I have been trying to create a variable and then insert it into Child Selector using jQuery i.e. $("parent > child") with no luck.
I have included the entire applicable segment of jQuery code as reference, the overall idea is that when a navigation button is clicked, the class ".is-checked" is added to the navigation button ".nav-collapse". Each button is associated with a unique data-filter that is applied via jQuery Isotope.
The issue I am having is that later on in the code, I am then trying to correctly call out the associated checked navigation button's data-filter (using the var = sclass) and apply this as a selector via the Child Selector $("parent > child") but have been having trouble getting this to work.
Issue is with the last 2 lines of code:
$('.nav-collapse').on( 'click', 'button', function( event ) {
var $target = $( event.currentTarget );
$target.toggleClass('is-checked');
var isChecked = $target.hasClass('is-checked');
var filter = $target.attr('data-filter');
if ( isChecked ) {
addFilter( filter );
} else {
removeFilter( filter );
}
$grid.isotope({ filter: filters.join(',') });
$(".masonry-image a").click(function(){
var sclass = $('.nav-collapse.is-checked').children().attr('data-filter');
$(" li." + sclass + " > a[href$='-hi.jpg']").addClass("fancybox-button")
...
However, if I change the selector "parent" to an existing selector li class="li class1", for example:
$(" li.class1 > a[href$='-hi.jpg']")
then the functionality I am going for works effectively, so I know I am on the right track. I have not been able to find any examples of creating a variable then inserting it as the parent within the selector, so I am not sure if my issue lies within how I have set up the selector, or how I have constructed the variable, or both.
<nav class="nav-collapse">
<ul>
<li><button class="button" data-filter=".class1">Class 1</button></li>
<li><button class="button" data-filter=".class2">Class 2</button></li>
<li><button class="button" data-filter=".class3">Class 3</button></li>
</ul>
</nav>
<li class="masonry-image class1">
<a href="images/shared/00001-hi.jpg">
<img src="images/shared/00001.jpg" width="308" height="205" alt=""/>
</a>
</li>
<li class="masonry-image class2">
<a href="images/shared/00002-hi.jpg">
<img src="images/shared/00002.jpg" width="308" height="205" alt=""/>
</a>
</li>
Did you even check your sclass? Console.log is your friend ;)
As .children only travels down 1 level it will only check the UL. It will never reach the button.
Try:
var sclass = $('.nav-collapse.is-checked').find("button").attr('data-filter');
Or:
var sclass = $('.nav-collapse.is-checked button').attr('data-filter');
EDIT: oops I misinterpreted your code, I think you need:
var sclass = $('.nav-collapse').find('.is-checked').attr('data-filter');
Or this (note the space!):
var sclass = $('.nav-collapse .is-checked').attr('data-filter');
For your last line of code remove the dot after the li, or remove the dots from the data-filters.
I have this code http://jsfiddle.net/cwahL1tz/
My HTML
<ul class="myFilters">
<li data-type="A">A</li>
<li data-type="B">B</li>
<li data-type="C">C</li>
</ul>
<div class="filter">
<ul class="title">
<li>Assurance</li>
<li>Couverture</li>
<li>Banque</li>
<li>Alimentation</li>
</ul>
<div id="Assurance" class="category">
<ul>
<li>Groupama</li>
</ul>
</div>
<div id="Couverture" class="category">
<ul>
<li>Try it !</li>
</ul>
</div>
<div id="Alimentation" class="category">
<ul>
<li>AN example</li>
</ul>
</div>
</div>
Here's my JS script
jQuery(function ($) {
$('.myFilters li').click(function(){
$(".category").hide();
var v = $(this).text()[0]
$('.title li').hide().filter(function(){
return $(this).text().toUpperCase()[0] == v;
$(".category:first").show();
}).show()
})
$("a[data-toggle]").on("click", function(e) {
e.preventDefault(); // prevent navigating
var selector = $(this).data("toggle"); // get corresponding element
$(".category").hide();
$(selector).show();
});
});
It works fine but I trying to arrange some stuff but I'm stuck.
When I load the page all the links and divs appears, I just only want the divs of the first letter appear.
And when I click on C for example, I want the first div to show from the first link.
Thanks for your help !
EDITED:
On load:
$('.myFilters li:first').trigger('click');
And inside its click:
.first().find('a[data-toggle]:first').trigger('click');
jsfiddle DEMO
You can simply do that with first selecting the element with the right selector and then you can trigger the click event manually :
Show the Assurance content on load :
$('a[data-toggle="#Assurance"]').click();
Show first content on click :
$('.myFilters li').click(function(){
$(".category").hide();
var v = $(this).text()[0]
$('.title li').hide().filter(function(){
return $(this).text().toUpperCase()[0] == v;
}).show()
$('a[data-toggle]:visible:first').click();
})
Updated jsFiddle
Without going into any more javascript, you can display the content the way you would like using css selectors:
.category {display:none;}
.category:nth-of-type(1) {
display:block;
}
http://jsfiddle.net/5ageasm4/1/
Is this what you want. Check the Fiddle
I am basically just triggering the first item in the li
$(".title > li:first").find("a[data-toggle]").trigger("click");
and i am doing the same with the category.
EDIT
I updated my Fiddle
NEW EDIT
Created a new Fiddle, this one just removes all the duplicate code.
So basically i created these 2 functions
that.selectFirstElem = function(selector){
selector.find("a[data-toggle]").trigger("click");
};
that.loadFirstDataToggle = function(input){
return $('.title li').hide().filter(function(){
return $(this).text().toUpperCase()[0] == input;
}).show();
};
And those 2 functions you can just call in the places where you need it.
I have the following code structure:
<ul class='menu'>
<li>
Main Menu
<ul class='hide'>
<li>SubMenu1</li>
<li>SubMenu2</li>
</ul>
</li>
<li>
Main2
<ul class='hide'>
<li>Sub1</li>
</ul>
</li>
</ul>
Is there a way for me to have a jQuery click event on Main Menu and Main2 in a generic way that will remove the class 'hide' of the correct children each time?
Here is another way, which uses event delegation and only runs when the li element and not its children was clicked:
$('ul.menu').on('click', 'ul.menu > li', function(e) {
if(e.target === this) {
$(this).children('ul').toggleClass('hide');
}
});
DEMO
$("ul.menu > li").on("click", function () {
$(this).children("ul").removeClass("hide");
});
Example: http://jsfiddle.net/dpkBL/
Dont always do what the crowd tells you, at least think about it for a while!
I bet people will recommend you to use a selector such as ul.menu > li, but please remember that this will not only trigger a click event when you click on the text "Main Menu", but also when you click on any of the other content inside the matching li.
If you'd like to implement a show/hide toggle you are far better off wrapping the text "Main Menu" inside it's on element, and then use something as the below to alter what you may want to alter.
$(<main menu text selector>).siblings (<siblings selector>);
Still want/have to follow the crowd?
If this is the case I'd recommend you to at least do it with a little twist to prevent what I previously described.
(edit: revised version after reading the jquery documentation for elements)
$('ul.menu > li').click (function(e){
if (e.target === this) {
$(this).children ('.hide').removeClass ('hide');
}
});
$("ul.menu > li").click (function () {
$(this).find ('.hide').removeClass ('hide');
});
$("ul.menu > li > *").click (function () {
return false; // prevent event from bubbling up
});
Sample implementation of recommended version
The below will bind a click-event-listener to .menu-toggle, when the event is fired the siblings (ie. the tags who are in the same scope as the clicked .menu-toggle) matching .hide will have their class="hide" removed.
Javascript
$(".menu-toggle").click (function () {
$(this).siblings ('.hide').removeClass ('hide');
});
HTML
<ul class='menu'>
<li>
<span class="menu-toggle">Main Menu</span>
<ul class='hide'>
<li>SubMenu1</li>
<li>SubMenu2</li>
</ul>
</li>
<li>
<span class="menu-toggle">Main2</span>
<ul class='hide'>
<li>Sub1</li>
</ul>
</li> </ul>
Take a look at the child selectors. I think that is what you want.
$('.menu > li').click(function () {
$(this).children('ul').removeClass('hidden');
});