If I have an html structure like:
<div id="parent">
<div class="child first">
<div class="sub-child"></div>
</div>
<div class="child second">
<div class="sub-child"></div>
</div>
<div class="child third">
<div class="sub-child"></div>
</div>
</div>
and I have a click handler defined through ($('#parent.child')).click() and then I click on the div with the class of second (first, second, third classes have simply been added to make demo clearer) is there a simple way to get the number 1 as it is the second child? (0 based index)?
Something like $(this).index
Just have a look at the jQuery API. The method you suggest, index, is exactly right:
$('#parent .child').click(function() {
var index = $(this).index();
});
From the docs:
If no argument is passed to the .index() method, the return value is
an integer indicating the position of the first element within the
jQuery object relative to its sibling elements.
Also note that I've changed the selector slightly from your example. I'm guessing that was just a typo in your question though. #parent.child will look for an element with ID "parent" and a class of "child", but you actually want #parent .child (note the space) to find elements with class "child" that are descendants of an element with ID "parent".
The index() method can be used for getting the position of an element inside a collection. In basic circumstances, $(this).index() should work.
But with more specific collections, you can get the position with collection.index(item). Imagine adding something simple into your #parent that should not be counted when measuring index() (a span, img, anything). With the simple method, your code is likely to break, but with the specific method, it won't.
Something like this should work for you:
var $children = $('#parent .child').click(function () {
console.log($children.index(this));
});
jsFiddle Demo
Related
I need the jQuery statement to find ".findme" in this code:
$('.clicky').click(function() {
// the .find() method doesn't do it
$(this).find('.findme').css('color', 'red');
});
<div class='clicky'></div>
<div class='brother'>
<div class='findme'>Here I am</div>
</div>
I've tried variations on .find() and .next() and .children() and I can't quite work it out....
this in $(this).find('.findme') actually refers to the element that was clicked (the div with the class clicky.
.find() actually searches the descendants of the element you call it on, and since "findme" is not within the "clicky" div, it doesn't find it.
You should instead use jquery's .next() function to get the sibling immediately following the "clicky" div (that's the "brother"), and then search there for the "findme" div.
$(this).next().find(".findme").css("color", "red");
you may can try to change
$('.clicky').click(function() {
// the .find() method doesn't do it
$(this).siblings().children('.findme').css('color', 'red');
});
and i think you miss the click me inner text for the div
<div class='clicky'>click me!!!</div>
<div class='brother'>
<div class='findme'>Here I am</div>
</div>
I have the following structure in DOM:
<div class="parent">
<div class="child0"></div>
<div class="child1"></div>
<div class="child2"></div>
<div class="child3"></div>
<div class="child4"></div>
<div class="child5"></div>
...
</div>
what i try to do in javascript is to show only specific elements and hide the others like this:
showItems(0,3,'.parent'); // show child 0,1,2
function showItems(offset,limit,component)
{
$(component).children().hide();
for(var i=offset;i<=(offset+limit);i++)
{
$(component+':nth-child('+i+')').show(); //!!! does not make them visible
}
}
any idea?
Thanks!
You need a space between component and :nth-child. because now you are selecting any element with class "parent" that's also the nth-child.
You should make it easier and use the .eq() method instead, like this:
function showItems(offset,limit,component)
{
$(component).children().hide();
for(var i=offset;i<=(offset+limit);i++)
{
$(component).children().eq(i).show(); //this will work!
}
}
Just to add to the answer by Remco, add '>' to make sure you select only one of the immediate childs.
So, one way can write
$(component+' > :nth-child('+i+')').show();
or even better
$(component+' > div:nth-child('+i+')').show();
If you do not place the '>' symbol, it can also select the elements inside child divs, if it is present.
Basically I want to be able to select the div level2 parent from the child level4 div. My application does not has such classes, otherwise I'd just select level2 :)
<div class="level1">
<div class="level2">
<div class="level3">
<div class="level4"></div>
</div>
</div>
<div class="level2"> <!-- this is hidden -->
<div class="level3">
<div id="start" class="level4"></div>
</div>
</div>
</div>
I start with $('#start') and search for the first parent which is visible, but I'm not seeing a way to return the child of that parent. Searching for $('#start') inside the parent seems very wasteful as I start with a sub child to begin with.
$('#start').closest(':visible') // returns level1
$('#start').closest(':visible').first() // returns the first level2. I can't just use second because the number of level2s can change.
$('#start').closest(':visible').children().each(function(){ /* do some search to check it contains `$('#start')` }) // seems very wasteful.
Another way to look at what I'm trying to say would be; start in the middle, find the outside (the visible element), and move one element in.
How about this:-
$('#start').parentsUntil(':visible').last();
This will give you all hidden parent div's until its visible parent and last() wil give the outermost parent which is hidden. last is not a selector on position it is the last() in the collection.
You want the .has() method
Description: Reduce the set of matched elements to those that have a descendant that matches the selector or DOM element.
$('#start').closest(':visible').children().has('#start');
See fiddle for example.
You say that the classes don't exist...why not add them? It would make thinks much easier to find. The class names don't need to have actual styles associated.
var allLevel4 = $('#start').closest(':visible').find('.level4');
var firstLevel4 = $('#start').closest(':visible').find('.level4')[0];
var secondLevel4 = $('#start').closest(':visible').find('.level4')[1]; //also, #start
Use .filter():
$('#start').closest(':visible').children().filter(':first-child')
.find() is also good for selecting pretty much anything.
So I have a div with some child elements and when I select one with jQuery I want to get the index of it within a selector
<div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="blue"></div>
<div class="red"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="red"></div>
</div>
So lets say that I have the last element in the main div selected. If I call index() on it it will give me '7' because out of all the child elements the index is '7'. But now lets say I want to get the index based on the other 'red' elements, the goal is to return a value of '4' because out of all of the 'red' elements it is the fifth one. I looked through the documentation and didnt find a whole lot, then I experimented with putting selectors in the index() method like index('.red') but I couldn't get anything working.
Well, the documentation says:
.index( element )
element The DOM element or first element within the jQuery object to look for.
So can do:
selectedElements.filter('.red').index(this);
If you don't have selectedElements already, you can select corresponding siblings with, for example:
$(this).parent().children('.red')
If every element has only one class and then the filter can be dynamic:
var index = $(this).parent().children('.' + this.className).index(this);
Use the .index() function documented here
For the above if one wants to get the index of a element of the red class use $('div .red').index(elem);
$('div .red) will create a list of the elements with the red class within the div. .index(elem) will search for the elem within the array.
Running through all of them using id=test as parent
DEMO : http://jsfiddle.net/T7fXR/
$('#test > div').each(function(){
var thisClass=$(this).attr('class');
$(this).css('background',thisClass );
/* get index based on class*/
var idx=$('.'+thisClass).index(this);
$(this).text('Index= '+idx)
})
For me, this works just fine with your given HTML:
$('div').eq(5).index('.red') // 3
You can place selectors into the .index() function.
I have an ajax call that returns a HTML fragment. I am trying to select a div in that fragment before rendering.
An example of the HTML:
<div class="event-detail repBy-container">
<div class="copy">.....</div>
<div class="links">
....
</div>
<div class="contacts">
<div class="name-brand">....</div><div class="details">...., ...</div>
</div>
</div>
Now the problem:
function ajaxReturn(data) {
alert($(data).find('.event-detail').length); <-- Returns 0
alert($(data).find('.copy').length); <-- Returns 1
}
Is this a bug or am I doing something wrong?
.find() gets descendants only, not from the current level, you'd need .filter() to get items from the current set (which is the root of what you returned), like this:
function ajaxReturn(data) {
alert($(data).filter('.event-detail').length); //<-- Returns 1
alert($(data).find('.copy').length); //<-- Returns 1
}
If you want .find() to work in both cases, add the content to a parent container, like this:
function ajaxReturn(data) {
var parent = $("<div />").append(data);
alert(parent.filter('.event-detail').length); //<-- Returns 1
alert(parent.find('.copy').length); //<-- Returns 1
}
This is the expected behavior.
You are searching for .event-detail under your div and there isn't any.
You are searching for .copy under your div and there is one.
It depends on what is being passed into the ajaxReturn function. ie what does data contain?
If it contains the HTML you quoted then this is expected behaviour. This is because the .find() method searches within the current context, not including it. If the outer div in your example is the outer div in data then .find() will be searching for .event-detail inside of that div.