Randomize a sequence of div elements with jQuery

纵饮孤独 提交于 2019-11-26 07:22:55
Russ Cam
$('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};
whitebrow

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);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!