web-dev-qa-db-fra.com

Randomisez une séquence d'éléments div avec jQuery

J'essaie de faire mes premières étapes avec jQuery mais j'ai du mal à comprendre comment trouver une liste d'éléments enfants à partir d'un élément parent div. J'ai l'habitude de travailler avec ActionScript 2 et ActionScript 3, donc je pourrais me tromper sur un concept, comme quelle est la meilleure façon de randomiser une séquence d'éléments div avec jQuery!

J'ai cette simple portion de code 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>

J'ai essayé une façon de le faire comme map . Member divs dans un tableau puis en changeant l'ordre de tri mais sans succès.

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"));

quand j'ai essayé d'alerter element_parent [0] j'ai pensé obtenir le premier enfant de ma . membre liste de divs mais ce n'est pas le cas.

si je fais une alerte avec element_parent [0] .innerHTML je vois que:

<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>

Pourquoi? Comment puis-je faire pour obtenir exactement l'un des membres comme celui-ci?

<div class="member">
    <ul>
        <li>Paul</li>
        <li>McCartney</li>
    </ul>
</div>

Je suis sûr que cela devrait être facile, mais je ne sais pas comment :(

s'il vous plaît aider
Merci
vittorio


ÉDITER:

Merci pour la rapidité et ces différentes façons d'obtenir les enfants sélectionnés, je vais prendre note de ces façons pour l'avenir!
J'ai essayé ces méthodes, mais il semble que je n'ai pas pu obtenir la totalité du div (dites-moi si je me trompe, ça pourrait être trop possible !!).

Je devrais obtenir ce contenu:

<div class="member">
    <ul>
        <li>Ringo</li>
        <li>Starr</li>
    </ul>
</div>

mais avec l'une de ces méthodes comme $ ("div.band div.member: eq (2)") ou les autres moyens utiles, j'obtiens ceci:

alert ($('div.band div.member')[0]);
/* result
<ul>
    <li>Ringo</li>
    <li>Starr</li>
</ul>
*/

existe-t-il donc un moyen d'obtenir le conteneur . member div aussi dans mon nœud?

54
vitto
$('div.band div.member');

vous donnera un objet jQuery contenant <div> qui correspondent au sélecteur, c'est-à-dire div avec la classe member qui sont les descendants d'une div avec la classe band.

L'objet jQuery est un objet de type tableau en ce que chaque élément correspondant se voit attribuer une propriété numérique (pensez comme un index) de l'objet et une propriété length est également définie. Pour obtenir un élément est

// first element
$('div.band div.member')[0];

ou

// first element
$('div.band div.member').get(0);

Au lieu de sélectionner tous les éléments, vous pouvez spécifier de sélectionner un élément spécifique en fonction de la position dans le DOM. Par exemple

// get the first div with class member element
$("div.band div.member:eq(0)")

ou

// get the first div with class member element
$("div.band div.member:nth-child(1)")

MODIFIER:

Voici un plugin que je viens de supprimer

(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);

Voici un Démo de travail. ajoutez /éditez à l'URL pour voir le code. Si vous avez besoin de détails sur son fonctionnement, veuillez laisser un commentaire. Cela pourrait probablement être rendu plus robuste pour gérer certaines situations (comme s'il y a d'autres elems enfants de l'objet jQuery auquel le plugin est chianed), mais cela conviendra à vos besoins.

Code de la démo

$(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>
94
Russ Cam

J'ai modifié la solution de Russ Cam pour que le sélecteur soit facultatif et que la fonction puisse être appelée sur plusieurs éléments de conteneur, tout en préservant le parent de chaque élément aléatoire.

Par exemple, si je voulais randomiser tous les LI dans chaque div '.member', je pourrais l'appeler comme ceci:

$('.member').randomize('li');

Je pourrais aussi le faire comme ceci:

$('.member li').randomize();

Donc, les deux façons d'appeler cela sont les suivantes:

$(parent_selector).randomize(child_selector);

OR

$(child_selector).randomize();

Voici le code modifié:

$.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;
};

Minifié:

$.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};
25
gruppler

La randomisation à l'aide du tri ne randomise pas toujours les éléments. Il est préférable d'utiliser une méthode aléatoire comme celle de Comment puis-je mélanger un tableau?

Voici mon code mis à jour

(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);
6
whitebrow