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.
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 wonder why this onclick work on this div:
<div id="block-block-contact" class="block-factice expanded" onclick="sessionStorage.contactclass=this.className ">
but not on this li
<li id="dhtml_menu-1895" class="first collapsed dhtml-menu collapsed start-collapsed menu-1895" onclick="sessionStorage.menu1895=this.className">
meaning when i click on the div, it does store the contactclass variable whereas when i click on the li, it does not store the menu1895 variable
Matoeil,
Can you please check this
https://jsfiddle.net/612ee2df/
<ul>
<li id="dhtml_menu-1895" class="first collapsed dhtml-menu collapsed start-collapsed menu-1895" onclick="sessionStorage.menu1895=this.className">
Test
</li>
</ul>
jQuery
$(document).ready(function(e)
{
$('ul li').on('click',function(e)
{
var cls = $(this).attr('class');
alert(cls);
sessionStorage.menu1895 = cls;
})
})
Because I tried your code-snippet but instead of JavaScript I used jQuery & it saved the value in session storage.
another event was linked to this element.
To strip all event listeners i did
var old_element=document.getElementById("dhtml_menu-1895");
var new_element = old_element.cloneNode(true);
old_element.parentNode.replaceChild(new_element, old_element);
and now it works
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-...')
I have the follow html:
<ul id="myList">
<li>
<a class="myListItem li-selected">One</a>
</li>
<li>
<a class="myListItem">Two</a>
</li>
<li>
<a class="myListItem li-selected">Three</a>
</li>
<li>
<a class="myListItem">Four</a>
</li>
<li>
<a class="myListItem">Five</a>
</li>
</ul>
The li-selected class is added when the respective <li> tag is getting selected.
I am trying in $(document).ready() to check if any of the li's is selected (having li-selected class).
As a result I am expecting a boolean to use every time the page loads to pass it in an other function as a parameter.
I am trying something like this but it doesn't return true although it should:
$(document).ready(function() {
.
.
.
var hasSelectedItems = $("#myList li").find("a").hasClass("li-selected");
console.log(hasSelectedItems);
.
.
.
});
Expected result:
hasSelectedItems === true then at least one <li> is selected.
hasSelectedItems === false then no <li> is selected.
SOLVED
As it turned out there was nothing wrong with the way I was trying to check if the li-selected class existed but with the when I was trying to do it. I misplaced the var hasSelectedItems = $("#myList li").find("a").hasClass("li-selected"); part and tried to find a class that hadn't been added yet. So I moved that part of the code to run when the elements are rerendered after the addition of the li-selected class and it works.
Please use the following jquery code to find a tag:
$(document).ready(function() {
var lis = $("#myList li a.li-selected").length;
if(lis > 0)
{
//code here
}
else
{
//empty
}
});
You can rather find the length of anchor elements that have class li selected:
var lis = $("#myList li a.li-selected").length > 0 ;
I have a HTML markup that looks like
<ul>
...
<li>
<ul class="x">
...
<a href="#"...
How can I get the parent ul.x element from a click event hooked on the link?
this.parentNode works if the UL is the parent element, but if it's one of the ancestors I have to use this.parentNode.parentNode depending on how many parent elements are in between...
Can I somehow get the first UL parent?
Since you've tagged the question as jQuery:
$(this).closest("ul"); //Get the first ancestor `ul`
$(this).closest("ul.x"); //Get the first ancestor `ul` with class `x`
Or, without jQuery (since your example doesn't seem to be using jQuery):
var node = this;
while(node.tagName !== "UL") {
node = node.parentNode;
}
use closest(). this will get the closest ancestor that matches the selector you provide it.
$(function(){
$('a').on('click',function(){ //handler of your <a>
var ulx = $(this).closest('ul.x'); //find the closest ancestor <ul> with class "x"
});
});
For performance,
You can also use jquery on like below, jquery eventObject also has a property named delegateTarget, which could be useful in your case.
$('ul.x').on('click', 'a', function(e){
//e.delegateTarget is the parent ul of the clicked a tag
//e.target.id is the clicked a tag
alert(e.delegateTarget.id);
alert(e.target.id);
});
HTML:
<ul id='a' class="x">
<li><a id='1' href="#">A</a></li>
<li><a id='2' href="#">B</a></li>
<li><a id='3' href="#">C</a></li>
</ul>
<ul id='b' class="x">
<li><a id='11' href="#">1</a></li>
<li><a id='21' href="#">2</a></li>
<li><a id='31' href="#">3</a></li>
</ul>
In terms of performance, you are not binding the event on all the a tags. jQuery suggests this way.
Here is the fiddle.
Usually you would use .closest() like:
$('a').click(function(){
var ul = $(this).closest('ul.x'); //or just closest('ul') in case you only used the x for demo purposes
});
This will go up the DOM tree and stop at the first match (your ul.x-element).
if ul.x is direct parent of a use this:
$('a').on('click',function(){
var ul = $(this).parent('ul.x');
});
or
$('a').on('click',function(){
var ul = $(this).closest('ul.x');
});