How do I cycle through a group of jQuery elements - 4 at a time?
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 thinki开发者_Go百科ng:
- 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. :)
精彩评论