I know I can do this, I'm just getting lost in the hierarchy and need a second set of eyes on this.
Here's the structure 'm working with:
<div class="nav-column">
<ul>
<li>Link 01
<div>
<ul>
<li>Sublink 01</li>
<li>Sublink 02</li>
<li>Sublink 03</li>
</ul>
</div>
</li>
<li>Link 02</li>
<li>Link 03</li>
</ul>
<div class="home"><h3>Underlying Div</h3></div>
</div>
I am looking to do the following: when you hover over a .nav-column ul li a that visibility of div.home would turn off. Of course there are going to be multiple .nav-columns so I'm making this dynamic.
The jQuery I have right now is:
if ($('.nav-column li').hasClass('active')){
$(this).parent('.nav-column').sibling('div.home').toggleClass("off");
}
without yielding any class addition to the div.home. I already have a hover function adding and removing the class '.active' to the .nav-column li
EDIT EDIT EDIT
I see that I have made a mistake with my code, and in fact the correct code has the div.home OUTSIDE the div.nav-column
This is the proper heirarchy:
<div class="wrapper">
<div class="nav-column">
<ul>
<li>Link 01
<div>
<ul>
<li>Sublink 01</li>
<li>Sublink 02</li>
<li>Sublink 03</li>
</ul>
</div>
</li>
<li>Link 02</li>
<li>Link 03</li>
</ul>
</div>
<div class="home"><h3>Underlying Div</h3></div>
</div>
Once again... I am very sorry... you can sense my sanity levels dropping
Think this is what you want:
$('.nav-column li').each(function(){
if($(this).hasClass('active')) {
$(this).closest('.nav-column').siblings('div.home').toggleClass("off");
}
});
Fiddle:
http://jsfiddle.net/Jf8mp/
Your mistakes:
.sibling('div.home') is wrong, the correct name of method is .siblings()
if condition doesnt determine who is $(this), you have use a function as .each()
UPDATED:
to make it work on hover over .nav-column ul li a:
$('.nav-column li').on('mouseenter','a',function(){
if($(this).closest('li').hasClass('active')) {
$(this).closest('.nav-column').siblings('div.home').toggleClass("off");
}
});
Fiddle:
http://jsfiddle.net/Jf8mp/2/
You need to use .parents() instead of .parent(). .parents() traverses up multiple levels of the DOM while .parent() retrieves the immediate parent of the element matching the selector.
$(this).parents('.nav-column').siblings('div.home').toggleClass("off");
Since you're not targetting the direct parent (ul) of the element matching the selector, you'll need to use .parents() instead.
In addition, you have a second problem. According to your code structure div.home is not a sibling of .nav-column. You can use .find() for this instead.
Per your last edit, the previous statement is no longer applicable. The code snippets have been updated to reflect your edited change.
Alternatively, you could do the following to accomplish the same effect:
$(this).parents('.nav-column').next().toggleClass("off");
use .closest() or .parents() instead of .parent(). also div home is not sibling of .nav-column. You need to use .find() instead of .siblings().Try this:
$(this).closest('.nav-column').find('div.home').toggleClass("off");
or
$(this).parents('.nav-column').find('div.home').toggleClass("off");
the .parent() only goes up one node, you need to use .parents('select')
If I understand:
$('.nav-column li').forEach(elem, index){
elem = $(elem);
if (elem.hasClass('active')){
elem.addClass("Cheese");
}
}
This would add the class "Cheese" to any active li :)
Related
I have a set of elements
<div id="lista">
<ul>
<li class="seto">Element 1</li>
<li class="seto">Element 1</li>
<li class="seto">Element 1</li>
</ul>
</div>
Then i'm using jquery, it's better do this?:
$("#lista li").each(function(){ //something };
or this?:
$(".seto").each(function(){ //something });
Thanks.
You can read about selector optimizatoin here:
https://learn.jquery.com/performance/optimize-selectors/.
The $("#lista").children('li') will be the fastes.
But in your case performance is not so important, so you can use whatever you prefer.
Performance will not be an issue I think.
Your jquery should reflect your intent of the code.
Depending of your want to apply styling, I would choose the class version.
If you want to do some post-processing on specific business objects, I would use the ID version.
Having said that, I think you should use the class version, and make sure that the business objects have the correct classes to attach the styling to. Including jQuery functions.
It depends upon your case
Case 1:
For exxample ur case is like this means
<div id="lista">
<li class="seto">Element 1</li>
<li class="seto">Element 1</li>
<li class="seto">Element 1</li>
<ol class="seto">diff Element 1<ol>
</div>
If you want to go through list of all "seto" contain class elements
Then u go for second method. Or else you can use first method
This should be pretty simple. Basically when an item in a list is clicked that text is inserted/replaced into a target div. 'replaceWith' is probably not the thing to use because it deletes the original data.
Also how do you add the class of 'selected' to the text in the target div.
Anyway here is what I have so far: http://jsfiddle.net/BM8Cb/
HTML
<div class="selected" id="here">
<li>All</li>
</div>
<hr>
<ul>
<li>All</li>
<li>Category 1</li>
<li>Category 2</li>
<li>Category 3</li>
</ul>
CSS
ul {list-style:none;padding:0; margin:0;}
li {cursor:pointer;}
li:hover {color:red;}
.selected {color:red;}
JS
$("li").click(function() {
$("#here").replaceWith(this);
});
Thank you for any help
What about
$("li.item").click(function() {
$("#here").html($(this).html());
});
If all you need is the text.
using replaceWith will replace the DOM node so it's no longer there the next time you try. You need to use append
$("#here").append(this);
and By using 'this' you are copy everything include the event handler. if you want just the text you can do something like
$("#here").append(this.innerHTML);
Change your JS to:
$("li.item").click(function() {
var item = $(this).clone();
item.attr("class","selected");
$(".selected").append(item)
$(this).hide();
});
Here's the fiddle: http://jsfiddle.net/J7JST/2/
This will also add the selected class to your item
How we can hide href element in specific UL element ( not in all UL elements, because UL elements are with the same name).
For example we have HTML code like this:
<ul class="UL_tag">
<li>Text 1</li>
<li>Text 2</li>
<li>Link to GOOGLE</li>
</ul>
<ul class="UL_tag">
<li>Text 1</li>
<li>Text 2</li>
<li>Link to Yahoo</li>
</ul>
And we can hide these href's by using this code:
$('a.description').hide();
How should I change this javascript code, if I want to hide just one href element which is in the one UL element? Not all href elements with the class name "description" ?
Thank you for your help!
You can use attr href selector:
$('a[href="http://www.yahoo.com"]').hide();
Here is an example links, which you can use with different methods:
http://api.jquery.com/attribute-contains-selector/
http://api.jquery.com/attribute-ends-with-selector/
And this questions also related: jQuery cant access element with its attr href // simple tabs structure
You can traverse the dom to get the element within the parent ul
$(this).parent().siblings().find('a.description').hide();
// get current clicked > parent li > siblings > find a.description in li siblings > hide
http://jsfiddle.net/CjfXu/1/
EDIT
Since your li is actually wrapped inside a span also.. .parent won't work as it's getting the span element. You need to use .closest() - which gets the closest ancestor that matches
$(this).closest('li').siblings().find('.description').hide();
Also don't bind a click event inside another click event as that causes the dom to attach multiple event handlers to the element. Always bind inside the document.ready function. Dynamically created elements or when you have many elements that you need to bind, using delegation would be the most efficient way.
You had your code like this
$('a.start').bind('click', function(){ // <-- this should be $('a:not(.start)').bind
// code
$('a.start').click(function(e) {
$(this).parent().siblings().find('.description').hide();
});
});
Which is binding any anchors with class=start a click event each time the first anchor is clicked
to use delegation
$('parentElement').on('click','element', function(){
})
or jQuery 1.6 and below
$('parentElement').delegate('element','click', function(){
});
You should give proper ids to each <ul>:
<ul class="UL_tag" id="firstList">
<li>Text 1</li>
<li>Text 2</li>
<li>Link to GOOGLE</li>
</ul>
<ul class="UL_tag" id="secondList">
<li>Text 1</li>
<li>Text 2</li>
<li>Link to Yahoo</li>
</ul>
And then:
$('#firstList a.description').hide();
HTML :
<ul class="UL_tag">
<li>Text 1</li>
<li>Text 2</li>
<li>Link to GOOGLE</li>
</ul>
<ul class="UL_tag">
<li>Text 1</li>
<li>Text 2</li>
<li>Link to Yahoo</li>
</ul>
Jquery:
var d = $('.UL_tag li').children('a')[1]; // If you remove first href element change it to value "1" to "0"
$(d).hide();
See this Demo: http://jsfiddle.net/7aNRZ/8/
select the element by tagname and class, and then filter for href value:
$('a.description[href="http://www.google.com"]').hide();
you can also limit the result to only elements inside the class .UL_tag:
$('a.description[href="http://www.google.com"]', '.UL_tag').hide();
Thank you for your answers, I think all of these answers are also correct answers, but what I'm trying to achieve is a bit different. Actually there is 3 li elements (two of them are with href tag):
<ul class="UL_tag">
<li>There you can download something.</li>
<li>Download</li>
<li>Link to GOOGLE</li>
</ul>
When you click on the "Download" link, javascript will be called:
$(function(){
var seconds = 10;
var canClick = true;
seconds *= 1000;
$('a.start').bind('click', function(){
if(canClick){
var link = $(this).attr('href');
var loader = $('input[name="link"]').val();
$(this).html('<img src="' + loader + '"/>');
setInterval(function(){
window.location.reload();
window.location = link;
}, seconds);
// Description will be hidden everywhere.
// How we can hide description in only one
// row. In row where the a.start was called?
$('a.description').hide();
canClick = false;
}
return false;
});
});
It will show the "loading gif" and after 10seconds user will beredirect to the download page.
So is it possible to hide "description" in only one row not everywhere. Just in a row where we call this "start" function?
The biggest problem is to hide just one li element, when all UL's and li's have same class name.
I have multiple list objects with the same structure on a page:
Example:
<div class="mainWrapper">
<div class="listWrapper">
<ul>
<li>Object One</li>
<li>Object Two</li>
<li>Object Three</li>
<li>Object four</li>
<li>Object five</li>
</ul>
</div>
<div class="listWrapper">
<ul>
<li>Object One</li>
<li>Object Two</li>
<li>Object Three</li>
<li>Object four</li>
<li>Object five</li>
</ul>
</div>
</div>
Using jQuery, how can I set it so that for each list, only the first 3 objects are showing in each list and the rest are hidden?
You can use :gt() pseudo selector which select all elements at an index greater than index within the matched set.
$('.listWrapper').find('li:gt(2)').hide();
Demo
Try the :gt() (greater than) selector:
$('.listWrapper ul').find('li:gt(2)').hide();
jsFiddle
It's necessary to query the targeted lis in two passes using an additional find(). Otherwise if there are multiple uls, all lis will be treated as a single collection, and only 3 total list items will be shown. This way we hide() selected items as many times as there are lists.
NOTE: You want your initial query to get down to the list itself.
See :gt() selector documentation.
http://jsfiddle.net/GEbxG/
$('div.listWrapper li').each(function(i, elem) {
if($(elem).index() < 3) return;
$(elem).hide();
});
$('.listWrapper li').show().slice(3).hide();
http://api.jquery.com/slice/
You can remove the .show() if all elements are visible initially.
If you don't already have the jQuery object containing all the li elements and/or don't need access to the full element list, you can avoid selecting them at the first place:
$('.listWrapper ul li:gt(2)').hide();
I have the usual unordered list for a navigation menu with submenus...
html:
<ul>
<li>Link 1</li>
<li>
Link with submenu
<ul>
<li>Sublink 1</li>
</ul>
</li>
</ul>
All of the links inside of the parent <li> have a border radius. But if the parent <li> has a child <ul>, I don't want the link to have a radius.
I'm currently using this jQuery:
<script>
$("li").has("ul").addClass("sub-radius");
</script>
It works fine except it's targeting the <li>, but I need it to target the child <a> and remove its radius.
Any help would be appreciated.
Try this expression:
$("li:has(ul) > a").addClass("sub-radius");
Edit: If you don't want the sub-items to have border-radii, remove the > in the query.
You don't need jQuery here, you can achieve that with CSS alone. Just use the :only-child pseudo-class:
a:only-child { /* define border-radius here */ }
Live demo: http://jsfiddle.net/QYaqb/
This should work for your HTML
("li").has("ul").children("a").addClass("sub-radius");
I think you want .find:
<script>
$("li:has(ul)").find("a").addClass("sub-radius");
</script>
just need to find the a's inside the li:
$("li").has("ul").find('a').addClass("sub-radius");
here's a fiddle:
http://jsfiddle.net/cBfMV/