I have this code:
var toLoad = $('.sidebar').find('.active').next('li.list-element').attr('data-id');
Which should detect the next element after my .active with list-element class. It doesn't. The problem is, I have a list like this:
<li class="list-element active">...</li>
<li class="list-element">...</li>
<li class="ads">...</li>
<li class="list-element">...</li>
<li class="list-element">...</li>
And when I get to ads, my script stops. What can I do?
.next() will only target the next element. You need to use .nextAll() along with :first or :eq(0) to target the next first sibling with the required class:
var toLoad = $('.sidebar').find('.active').nextAll('li.list-element:first').attr('data-id')
The problem is your understanding of the .next() method is wrong, it does not return the element element matching the selector, it will return the next sibling element only if it matches the passed selector
One easy solution is to find all the next elements then use the first one in the set
var toLoad = $('.sidebar').find('.active').nextAll('li.list-element:eq(0)').attr('data-id');
Jquery next()
Get the immediately following sibling of each element in the set of
matched elements. If a selector is provided, it retrieves the next
sibling only if it matches that selector.
So, when you write
$('.sidebar').find('.active')
That will find one element, the li with the class active and .next() can only select from within that group.
You could, however, use just one CSS selector to find the next element from the .active one like so:
$('.sidebar .active ~ li.list-element:first').attr('data-id')
~ is the general sibling selector that matches elements that are after the original element (.active) and share a parent (.sidebar).
Related
I have the following HTML structure and JavaScript file:
.html
<li>
<button class="show-more"></button>
some more elements
<div class="hidden"></div>
</li>
JavaScript
$( ".show-more" ).click(function() {
event.preventDefault();
$( this ).next().slideToggle( "fast", function() {
});
});
I need the click event to toggle the next first instance of .hidden, however the click event is targeting the first element after it and not the next instance of .hidden, any ideas how I can go about it?
nextAll and first:
$(this).nextAll('.hidden').first().slideToggle(...);
This question has more about this: Efficient, concise way to find next matching sibling?
Another possible solution:
$('~.hidden:first', this).slideToggle("fast");
This will match for the first, next sibling of the class .hidden in the context of this.
The ~-selector will reach all following siblings.
Demo
Reference
Next sibling selector
first selector
context of selector
Given the following html list:
<ul>
...
<li>
<li> // <-- item to be selected
<li>
<li class='current'>
<li>
<li>
<li>
...
</ul>
How do I select the li two instances ahead of the li with class current?
Any pure javascript or jquery solution would be great!
Making it more generic, i.e if you want to select a li possibly(2nd or 3rd or what ever instance that appears prior to your selector), then try
$('li.current').prevAll(':eq(' + n-1 + ')');
Here n would be the instance # that you are talking about (Since it is 0 based index). In your case this would be:
$('li.current').prevAll(':eq(1)');
Do remember that prevAll returns the elements in the order starting from the selector, so you can just provide the index of the element from that position in prevAll with eq selector.
Fiddle
Very easily:
$('.current').prev().prev()
You can try
$('.current').prev().prev()
This may help...
var li=document.getElementsByTagName('li');
var i, n;
for(i=0;i<li.length;i++)
{
if(li[i].className=='current')
{
n=(i+2)%(li.length);
}
}
var x=li[n];
I have accepted an answer. My own solution first identified the index of the element to be selected:
var index = $('.current').index()-n+1;
n equals the number of items you want to be ahead of the current object. The +1 is because indexing starts at zero, yet nth-child at 1.
I then used the nth-child selector to get the right element:
$('ul li:nth-child('+index+')')
I have some HTML blocks look like
<li id="item261">
<div class="itemdesc">
<a class="icon-hide">Hide</a>
</div>
</li>
And i have a jquery like
$(document).ready(function()
{
$('.icon-hide').click(function(){
var elemId = $(this).parent().attr("id");
});
});
I need the ID of the "li" tag on click of ".icon-hide". how can i achive this? any help..
I'd suggest:
$('.icon-hide').click(function(){
var elemId = $(this).closest('li').attr('id');
});
This is because parent() as implied in the name of the method looks at the parent of the element returned by the selector (the parent is the div); whereas closest() continues up the ancestor tree to match the first selector passed to the method.
You could, instead, use parents(), however the important difference between closest() and parents() is that closest() returns zero or one match, whereas parents() will continue all the way to the root element and return every match it finds, so it can return zero, one or many matches.
Another difference is that parents() starts searching from the current element's parent, whereas closest() starts with the current element itself, so it's quite easily possible, using closest() for the method to return the current/$(this) element itself.
References:
closest().
parent().
parents().
$(this).closest('li[id]').attr('id')
I am trying to get the parent <li> when I click on a specific <li> item.
http://jsfiddle.net/doonot/GjbZk/
So let's say I click on submodule 1, I get the clicked ID with $(this).attr('id');
How can I now get the ID of the parent <li> which is in this case module 1?
Please note that my tree is quite big, so it has to be flexible.
Thanks a lot, much appreciate your answer.
You can use the closest method to get the first ancestor that matches a selector:
var li = $(this).closest("li");
From the jQuery docs:
Get the first element that matches the selector, beginning at the
current element and progressing up through the DOM tree.
var parentModule = $('this') //the selector of your span
.parents('li:eq(1)') //get the next li parent, not the direct li
.children('.rightclickarea:first') //get the first element, which would be the span
.attr('id') //get the span id
var parent = $(this).closest("li");
This works:
link1
link2
link3
$("a[href*='#/link1'").next('a[href*="#"]').click();
but this does not:
link1<br>
link2<br>
link3<br>
$("a[href*='#/link1'").next('a[href*="#"]').click();
The above tests the "< br >" tag, not the next matching link.
How would I go about making it work in both situations. I want to select the next matching element, not the next element if it matches. Maybe .next() isn't the correct method?
The second example should not select anything at all. Read the documentation of next:
Get the immediately following sibling of each element in the set of matched elements. If a selector is provided, it retrieves the next sibling only if it matches that selector.
You have to use nextAll to get all siblings and filter them accordingly:
$("a[href*='#/link1']").nextAll('a[href*="#"]:first').click();
Reference: nextAll
Use .nextAll() and :first to get the next sibling that matches, rather than the next sibling if it matches, like this:
$("a[href*='#/link1'").nextAll('a[href*="#"]:first').click();
Create your own simple jQuery plugin called nextMatching:
$.fn.nextMatching = function(selector) {
return this.nextAll(selector).first();
};
And use it like this: given the following markup...
<li id="startingElement">one</li>
<li>two</li>
<li>three</li>
<li>four</li>
<li id="targetElement">five</li>
<li>six</li>
...and starting with the element one, you can select element five like this:
$('#startingElement').nextMatching('#targetElement');