I'm trying to do my frist steps with jQuery but I have some trouble to understand how to find a list of child elements from a div parent element. I'm used to work with ActionScript 2 and ActionScript 3 so i could mistake some concept, like what is the better way to randomize a sequence of div elements with jQuery!
I have this simple portion of HTML code:
<div class="band">
<div class="member">
<ul>
<li>John</li>
<li>Lennon</li>
</ul>
</div>
<div class="member">
<ul>
<li>Paul</li>
<li>McCartney</li>
</ul>
</div>
<div class="member">
<ul>
<li>George</li>
<li>Harrison</li>
</ul>
</div>
<div class="member">
<ul>
<li>Ringo</li>
<li>Starr</li>
</ul>
</div>
</div>
I have attempted some way to do that like map .member divs in one array and then changing the sort order but without success.
function setArrayElements (element_parent) {
var arr = [];
//alert (element_parent[0].innerHTML);
for (var i = 0; i < element_parent.children().length; i ++) {
arr.push (element_parent[i].innerHTML);
}
}
setArrayElements($(".band"));
when i attempted to alert element_parent[0] i thought to get the first child of my .member list of divs but it isn't.
if i make an alert with element_parent[0].innerHTML i see that:
<div class="member">
<ul>
<li>John</li>
<li>Lennon</li>
</ul>
</div>
<div class="member">
<ul>
<li>Paul</li>
<li>McCartney</li>
</ul>
</div>
<div class="member">
<ul>
<li>George</li>
<li>Harrison</li>
</ul>
</div>
<div class="member">
<ul>
<li>Ringo</li>
<li>Starr</li>
</ul>
</div>
Why? How can I do to get exactly one of the members like this?
<div class="member">
<ul>
<li>Paul</li>
<li>McCartney</li>
</ul>
</div>
I'm sure this should be easy but I just don't know how :(
please help
thanks
vittorio
EDIT:
Thanks for the fastness and this various ways to get the selected children, I'll take a note of these ways for the future!
I tried this methods, but it seems I couldn't get the entire div (please tell'me if i mistake something, it' could be too much possible!!).
I shoud get this content:
<div class="member">
<ul>
<li>Ringo</li>
<li>Starr</li>
</ul>
</div>
but with one of this methods like $("div.band div.member:eq(2)") or the other useful ways, I get this:
alert ($('div.band div.member')[0]);
/* result
<ul>
<li>Ringo</li>
<li>Starr</li>
</ul>
*/
so is there a way to get the .member div container too in my node?
$('div.band div.member');
will give you a jQuery object containing <div>
that match the selector i.e. div with class member
that are descendents of a div with class band
.
The jQuery object is an array-like object in that each matched element is assigned a numerical property (think like an index) of the object and a length
property is also defined. To get one element is
// first element
$('div.band div.member')[0];
or
// first element
$('div.band div.member').get(0);
Instead of selecting all elements, you can specify to select a specific element according to position in the DOM. For example
// get the first div with class member element
$("div.band div.member:eq(0)")
or
// get the first div with class member element
$("div.band div.member:nth-child(1)")
EDIT:
Here's a plugin I just knocked out
(function($) {
$.fn.randomize = function(childElem) {
return this.each(function() {
var $this = $(this);
var elems = $this.children(childElem);
elems.sort(function() { return (Math.round(Math.random())-0.5); });
$this.detach(childElem);
for(var i=0; i < elems.length; i++)
$this.append(elems[i]);
});
}
})(jQuery);
Here's a Working Demo. add /edit to the URL to see the code. If you need any details about how it works, please leave a comment. It could probably do with being made more robust to handle certain situations (like if there are other child elems of the jQuery object the plugin is chianed to) but it'll suit your needs.
Code from the demo
$(function() {
$('button').click(function() {
$("div.band").randomize("div.member");
});
});
(function($) {
$.fn.randomize = function(childElem) {
return this.each(function() {
var $this = $(this);
var elems = $this.children(childElem);
elems.sort(function() { return (Math.round(Math.random())-0.5); });
$this.remove(childElem);
for(var i=0; i < elems.length; i++)
$this.append(elems[i]);
});
}
})(jQuery);
HTML
<div class="band">
<div class="member">
<ul>
<li>John</li>
<li>Lennon</li>
</ul>
</div>
<div class="member">
<ul>
<li>Paul</li>
<li>McCartney</li>
</ul>
</div>
<div class="member">
<ul>
<li>George</li>
<li>Harrison</li>
</ul>
</div>
<div class="member">
<ul>
<li>Ringo</li>
<li>Starr</li>
</ul>
</div>
</div>
<button>Randomize</button>
I modified Russ Cam's solution so that the selector is optional, and the function can be called on multiple container elements, while preserving each randomized element's parent.
For example, if I wanted to randomize all LIs within each '.member' div, I could call it like this:
$('.member').randomize('li');
I could also do it like this:
$('.member li').randomize();
So the two ways to call this are as follows:
$(parent_selector).randomize(child_selector);
OR
$(child_selector).randomize();
Here's the modified code:
$.fn.randomize = function(selector){
(selector ? this.find(selector) : this).parent().each(function(){
$(this).children(selector).sort(function(){
return Math.random() - 0.5;
}).detach().appendTo(this);
});
return this;
};
Minified:
$.fn.randomize=function(a){(a?this.find(a):this).parent().each(function(){$(this).children(a).sort(function(){return Math.random()-0.5}).detach().appendTo(this)});return this};
Randomization using sort does not always randomize the elements. It is better to use a shuffle method like the one from How can I shuffle an array?
Here's my updated code
(function($) {
$.fn.randomize = function(childElem) {
function shuffle(o) {
for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};
return this.each(function() {
var $this = $(this);
var elems = $this.children(childElem);
shuffle(elems);
$this.detach(childElem);
for(var i=0; i < elems.length; i++) {
$this.append(elems[i]);
}
});
}
})(jQuery);
来源:https://stackoverflow.com/questions/1533910/randomize-a-sequence-of-div-elements-with-jquery