I am following a beginner video tutorial for Jquery and just went through this code: (inside .ready() )
$('ul li ').each(function(e){
$this().css{background' ,'red'}
$this().append(e);
});
now e prints each li index , can someone please explain me how does it get index for each item as it's not a loop .
Well, the .each() function is a loop. It almost literally says "For Each item that has the name 'ul li', do something."
The letter 'e' inside the parantheses is your actual index number. When you use an .each loop, the function gathers the number of whatever it's looking at and moves on until there are no more.
To simply show the number of the index, you can say:
$('ul li').each(function(i){ //I like to use the letter 'i' which more literally stands for 'index'
console.log(i);
});
This will show in your console as:
0
1
2
3
4
5
Assuming you have six of those elements.
Now, your use of $this means nothing. When using it properly it's written as $(this) which means "this element" since we're in a function that goes through each list element, it will take the list element it is currently looking at, then do whatever you want.
If you'd like the background color to be red of all of your list elements (like it seems you want to do) you would write:
$('ul li').each(function(i){
$(this).css({"background": "red"});
});
I'm not sure what you're trying to do with the .append function. By doing this, you're literally adding a list element to your list element for every list element!
Can you explain what you are trying to accomplish?
UPDATE
As your title says "Accessing every list item by its index," If you would like to access a particular list item, and not all of them, you can use the function .eq(). Let's say you have 6 list elements and you want the fourth one to have a red background. All you would have to do it this:
$('ul li').eq(3).css({"background":"red"});
Remember, index numbers start at zero, so the fourth one would be #3. (but of course, this would be faster and simpler in CSS!)
Actually, .each() is a loop/iterator. It will iterate over each of the elements that match. Eg: all the ul lis.
It will run through the code for every one it matches, and the DOM element will be accessible with $(this)
See the docs: http://api.jquery.com/jquery.each/
Related
Hello i got a ul list like this:
<ul><li>Test</li><li>Test</li></ul>
Now im appending from an array like this:
var array = new Array("Element1", "Element2");
var length = array.length;
I can only have 2 lines in my UL list (This is much more because i get information from a database)
So now the array has a length of two, then i use for to get the result but now i need it do delete the first rows, so if i add 12 li's i need it do delete the 12 first li's from the list, or if i add 2 li's i need it do delete the 2 first li's.
Anyone got a clue? Im kinda stuck right now
You can use .slice() to get a range of the elements matching a selector.
$("li").slice(0, -2).remove();
Using a negative number as the end of the range counts from the end of the collection.
I'm by no means a jQuery (or JavaScript) expert so forgive me if I'm misunderstanding or overlooking something. I have the following HTML:
<html>
<body>
<div class="ted">Ted</div>
<div class="ted">Ted</div>
<div class="tim">Tim</div>
<div class="ted">Ted</div>
<div class="tim">Tim</div>
</body>
</html>
And the following JS:
$('.ted').click(function() {
alert($(this).index());
});
When I click a div with the class '.ted' the alert should show the index of that div.
Clicking the first div alerts '0' (expected), the second div alerts '1' (expected). However, clicking the last '.ted' div (the fourth in the list) alerts '3' - why is this not giving an index of 2? (as JS arrays are 0 based) and this is the third '.ted' div?
It's as if $('.ted') is actually bringing back all the divs in the list?
Example here: http://jsfiddle.net/nha2f/6/
The .index() method docs make this behaviour clear. Here's the relevant part (emphasis added):
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.
Since the third element that matches your selector is actually the fourth child of its parent, it has an index of 3.
Continue reading through the documentation to find the solution to your problem:
If a selector string is passed as an argument, .index() returns an integer indicating the position of the original element relative to the elements matched by the selector.
So, you can pass the same selector to .index() and it will return the index of the element relative to the matched set:
alert($(this).index(".ted"));
.index() returns the index of the clicked element in it's parent, relative to it's siblings. Not compared to other divs with the same event listeners / class / id. Your third '.ted' div is the fourth child of your body.
To get the behavior you want, add a selector to your index call: Fiddle
$('.ted').click(function() {
alert($(this).index(".ted"));
});
When you pass a selector into index, it tells jQuery to look for the element in that set. If you don't, it looks to see where it is relative to all of its sibling elements.
Or alternately, remember the list of ted elements and then invert things: Fiddle
var teds = $(".ted");
teds.click(function() {
alert(teds.index(this));
});
When you pass an element into index, that tells jQuery to look for that element in the set.
the index is the child within the parent. If you want to enumerate the .ted elements try this:
$('.ted').each( function( i, a ){
$(a).click( function(){
alert( i ); // <- should be 0, 1 or 2.
} );
} );
I'm plucking my brain away at this but was hoping someone could help after several failed attempts.
I have an HTML list like this:
<ul>
<li><span class="current"></span></li>
<li><span class="normal"></span></li>
</ul>
I'm trying to figure out a way to find the li element in this list which has the span with the class current with the number it is at in the ul. So, in this case, it would be 1.
I tried using different jquery functions but I seem to be getting nowhere. This is what it looks like right now:
var list = $('ul li');
$.each(list, function(key, value) {
if( $(this).find('.current') ) {
alert(key);
}
});
This just alerts 0, and 1, essentially meaning that it doesn't work. Does anyone have any idea what is wrong with what I'm doing?
It would be 0 not 1 (JavaScript is zero-indexed), but:
$('li:has(span.current)').index();
JS Fiddle demo, and a larger-table example.
Or you could use:
$('span.current').parent().index();
JS Fiddle demo, and a larger-table example.
Or:
$('span.current').closest('li').index();
JS Fiddle demo, and a larger-table example.
References:
closest().
:has() selector.
index().
parent().
jQuery selectors (never) return a falsey value. So something like:
$(this).find('.current')
Will always return true in an if statement. An easy way to check for existence is with the length property, which says how many elements are found from the selector.
if ($(this).find('.current').length > 0) {
Your code loops through each item in the list and shows its key.
What you want is more like:
$('mylist').find('.current').each(function(key, value)
{
alert(key);
}
This will loop only through the items with class 'current'.
I'm a little confused. Basically, I've got 16 span elements on my page which are displaying brands. I want to show only 4 brands at a time, and then set an interval to show the next 4 brands until I reach the end, at which point I'll reset a counter and start from the beginning again. Here is what I was thinking:
Display all brand span elements
Put all of the brand elements into an array
Count first 4 items (brands) and give them the class of visible
After 5 seconds, hide all elements with class of visible
Display the next 4 items in the array
When the end of the array is reached, reset the counter and start again
Some general advice or help with jquery arrays would be appreciated. I'm looking for the most dynamic and simple solution possible.
Thanks :)
Here, it's a bit hackish though...
var elems = $( 'span' ).hide().get();
(function loop () {
var i = 0, pointer;
pointer = $( elems ).filter( ':visible:last' )[0] || $( elems ).last()[0];
$( elems ).hide();
while ( i < 4 ) {
pointer = $( pointer ).next()[0] || $( elems ).first()[0];
$( pointer ).show();
i += 1;
}
setTimeout( loop, 5000 );
})();
Live demo: http://jsfiddle.net/hBrt6/
If you require an explanation of the code, just let me know...
A few explanations:
.get() returns an array of the DOM elements inside the jQuery object.
So
$( 'div' ).get()
gives you an array of all the DIV elements on the page.
Using the property accessor operator [i] will give you the i-th DOM element from the jQuery object.
So
$( 'div' )[4]
returns the fifth DIV element on the page.
It is important to understand that you cannot invoke jQuery objects on DOM elements itself (or arrays of DOM elements).
So this
$( 'div' )[4].hide();
throws an error. DOM elements don't have a hide method.
If you want to target a specific element inside a jQuery object and while still retaining a jQuery object, use .eq().
This
$( 'div' ).eq( 4 ).hide();
works just fine.
Now that you understand this difference, let me explain why I use get() and [i] in my code: The thing is, I don't like to store jQuery objects inside variables. Instead I prefer to work with DOM elements and arrays of DOM elements directly.
When I need to invoke a jQuery method on some element or array of elements, I just wrap it inside the $() function first.
So this
$( elems ).hide();
works just fine.
And when the jQuery method has done the job, I just append .get() or [0] to "unwrap" the jQuery object = to get my element(s) back.
If the data exist as a JavaScript object then you can use JQuery templates to render the HTML.
You would do the following
Get all data in array of JavaScript objects (might already have this)
Empty the target element container you are inserting too ($('#target').empty())
Slice the array to only have the 4 elements you want (data.slice(index, index+4))
Render template into target element container with sliced array as the model ($('#template').tmpl(slicedArray).appendTo('#target'))
You should be able to do step 3 with a for loop that steps by 4. And in the template use the {{each}} method to loop over the row creation.
Ok, my solution will be as dynamic and simple as I will think to be possible. I'm good at making things like that and am quite good at jQuery and JavaScript so I thought I'd try my hand at this. I'll just write the best code I can think of here and show where you need to edit your other code after.
$("#ContainerElement.span:gt(4)").hide();
var i = 0;
var b = setInterval("BrandChange();",5000);
function BrandChange()
{
$("#ContainerElement.span:eq(i),
#ContainerElement.span:eq(i+1),
#ContainerElement.span:eq(i+2),
#ContainerElement.span:eq(i+3)").hide(normal,function(){
i+=4;
if(i == 16) i = 0;
$("#ContainerElement.span:eq(i),
#ContainerElement.span:eq(i+1),
#ContainerElement.span:eq(i+2),
#ContainerElement.span:eq(i+3)").show(normal);
});
}
I had to look up some jQuery selectors to figure this out, but that doesn't disprove it's validity, basically it first hides all the span elements in the Element which holds them, which will need an id of "ContainerElement" starts an interval for the BrandChange function, which fades out and hides the four current brands, then fades in and shows the next four brands, while incrementing the i variable to keep count, then it waits for the interval to happen again in five seconds. It's not necessarily the way you planned to do it, but I think you'll find it does exactly what you want it to. If you have any questions, just ask. :)
For example, I have a div with an id (lets say "the_div"). This div contains an unordered list, and this list has 5 items in it.
How would I add a class to the third list item, without any of the list items having a class attached to them?
Edit: Even better, how would I change the list item text to equal what number element it was?
Thanks.
Or...
$('#the_div ul li:eq(2)').addClass('className');
You can combine the selectors together - if you prefer :)
For your first problem, you can use eq, which is 0 based:
$('ul li', '#thediv').eq(2).addClass('whatever'); // add class to 3rd item
For your second problem, you can use each to iterate through all the list items. The callback function passes an argument containing the index of the current element in the set:
$('ul li', '#thediv').each(function(i) {
$(this).text(i); // update each list item with its index, 0 based.
});