jQuery: Shuffle Plugin

I recently came across a really compact array shuffling function on JSFromHell.com, which I thought would make a nifty jQuery plugin.

This jQuery shuffle plugin could be applied to any HTML element or Array object.

(function($){
  $.fn.shuffle = function() {
    return this.each(function(){
      var items = $(this).children();
      return (items.length) 
        ? $(this).html($.shuffle(items)) 
        : this;
    });
  }
	
  $.shuffle = function(arr) {
    for(
      var j, x, i = arr.length; i; 
      j = parseInt(Math.random() * i), 
      x = arr[--i], arr[i] = arr[j], arr[j] = x
    );
    return arr;
  }	
})(jQuery);

Due to line wrapping issues in this post I inserted a few hard carriage returns in the above snippet (sorry).

Example 1: shuffle an unordered list

$('ul').shuffle();

Example 2: shuffle an array

var arr = [1,2,3,4,5,6];
arr = $.shuffle(arr);

There is a demo here. And for those interested I encourage you to download the plugin for closer inspection.

  • http://raphamartins.com Raphael Martins

    Nice work! =)

  • http://mike.shannonandmike.net Mike B.

    Very nice script – thank you!

  • http://designbyelle.com.au/ Elle

    Nice script. Could I ask for your help on how to alter the script so it shuffles through an array but only shows just one array item — which would change on page reload?

  • caphun

    @Elle: Thanks. Yes that's certainly possible. Try this:

    jQuery(function($){

    var randomItem = $.shuffle([1,2,3,4,5,6])[0];

    alert(randomItem);

    });

    The above will return a random number between 1 and 6.

  • Pingback: Shuffling the DOM - James Padolsey

  • Pingback: Implement Array Shuffling in MooTools

  • Rustam Mester

    Big thanks to author from russian freelancer !

  • http://www.manishmistry.com Manish MISTRY

    Thanks mate!

  • http://blog.virgentech.com Hector Virgen

    Very nice! Just what I was looking for and it seems quick.

    But I ran into a small problem — all event bindings will be lost after shuffling. I made a small modification that allows you to keep your bindings by using clone(true):

    $.fn.shuffle = function()

    {

    return this.each(function()

    {

    var items = $(this).children().clone(true);

    return (items.length)

    ? $(this).html($.shuffle(items))

    : this);

    });

    };

  • caphun

    @hector – makes sense to keep the bindings! I will add that into my code aswell. Thanks!

  • Ellison

    Hello. I've made an attempt at extending this plugin a little to be able to seed a random number generator so that you can repeat sequences given the right seed. I'm very new at jQuery, so if I didn't do something quite right (style-wise or other), please tell me :)

    (function($){

    var getNextRandom = Math.random;

    $.fn.shuffle = function() {

    return this.each(function(){

    var items = $(this).children().clone(true);

    return (items.length) ? $(this).html($.shuffle(items)) : this;

    });

    }

    $.shuffleInit = function(options) {

    if(!options || !Random) return;

    if(typeof options.seed == "number") {

    var r = new Random(options.seed);

    getNextRandom = function() { return r.next(); };

    }

    }

    $.shuffle = function(arr) {

    for(var j, x, i = arr.length; i; j = parseInt(getNextRandom() * i), x = arr[--i], arr[i] = arr[j], arr[j] = x);

    return arr;

    }

    })(jQuery);

    It seems to work fine, assuming that you've loaded a class called Random that works appropriately (i.e. a 1-arg constructor to initialize the seed and a next() method to get the next pseudo-random number).

    Again, I'd much appreciate tips on how I can improve what I was trying to do.

  • http://www.bamboolabcode.com bamboolabcode

    Thanks for the info. I appreciate it well.

  • cordial

    this is exactly what i needed!

    perfect, thanks!

  • http://www.insideui.com Deepak

    really a good one… thanks for it.

  • http://www.simplmedia.ru Alvein

    Thanx. Powerfull script.. ;)

  • http://www.bewwweb.com Gérault thoma

    I think that I found an amelioration for the plugin shuffle

    [code]

    I did

    (function($){

    $.fn.shuffle = function(options) {

    defaults = {

    children: '',

    after:'',

    inside:''

    }

    if(options) params = $.extend(defaults,options);

    return this.each(function(){

    var items = $(this).find(params.children).clone(true);

    if(items.length){

    $(this).children(params.children).remove();

    if(params.after)

    return $.shuffle(items).insertAfter($(this).find(params.after));

    if(params.inside)

    return $(this).find(params.inside).html($.shuffle(items));

    else return $(this).html($.shuffle(items));

    }

    else return this;

    });

    }

    $.shuffle = function(arr) {

    for(var j, x, i = arr.length; i; j = parseInt(Math.random() * i), x = arr[--i], arr[i] = arr[j], arr[j] = x);

    return arr;

    }

    })(jQuery);

    [/code]

    example 1

    $('div').shuffle({'children':'.shuffle','after':'.field'});

    Example 2

    $('.random').shuffle({'children':'select > option:gt(0)','after':'select > option:lt(1)'});

    Example 3

    $('.random').shuffle({'children':'select > option:gt(0)','inside':'select'});

  • http://www.bewwweb.com Gérault thoma

    I made some code changes :

    (function($){

    $.fn.shuffle = function(options) {

    defaults = {

    children: '',

    after:'',

    inside:''

    }

    params = $.extend(defaults,options);

    return this.each(function(){

    if(params.children) var element = $(this).find(params.children);

    else var element = $(this).children();

    var items = element.clone(true);

    if(items.length){

    element.remove();

    if(params.after)

    return $.shuffle(items).insertAfter($(this).find(params.after));

    if(params.inside)

    return $(this).find(params.inside).html($.shuffle(items));

    else return $(this).html($.shuffle(items));

    }

    else return this;

    });

    }

    $.shuffle = function(arr) {

    for(var j, x, i = arr.length; i; j = parseInt(Math.random() * i), x = arr[--i], arr[i] = arr[j], arr[j] = x);

    return arr;

    }

    })(jQuery);

  • caphun

    I put .shuffle() up on github here:

    http://github.com/caphun/jquery.shuffle

    Feel free to fork it, modify and extend. Let me know if you do as I'm very much interested in how others will use this. :)

  • http://www.diasnormais.com Blude

    I'm not an expert on JavaScript but this seemed to works fine when I was testing local but when I uploaded to my blog it stopped working. It actually says that $.shuffle is not a function. Thanks for any suggestion on what might be causing this.

  • http://www.diasnormais.com Blude

    Nevermind. Just put my code wrapped inside (function($){

    })(jQuery); and now it's working fine. Thanks!

  • Pingback: Anonymous

  • Maclean

    Thanx, I was looking for this!

  • michelle

    what if its a multi dimensional array, will it shuffle just the rows or the whole array? sounds like a silly qu but quite imp. thanks

    • caphun

      @michelle: best way to find out is test it. If you hit problems drop a test case here.

  • http://www.jayminkapish.com/ Jaymin Patel

    Thanks. I am going to use this on my blog to shuffle quotes.

  • http://www.babelcoach.net Hector

    merci

    works like a charm.

    you've just saved me some hours of work :)

    I'll use this to shuffle some images for exercises.

  • OQMiv

    Thanks so much for the great script. I wonder, how would one need to write the function to shuffle the list on page load?

  • OQMiv

    This should work, no?

    <code>

    $('ol.shuffle').load(function(){

    $('ol').shuffle();

    });

    </code>

  • caphun

    try this:

    [sourcecode lang=""javascript""]

    jQuery(function($) {

    $('ol.shuffle').shuffle();

    });

    [/sourcecode]

  • OQMiv

    Fabulous. That syntax, edited for the id/class particulars of my site, works great.

    Many thanks!

  • Pingback: Working Class Globe Trotter | 7Wins.eu

  • http://benjamineheath.com ben

    great work! i like to donate to the developers whose work that i use. do you have a donate page?

  • caphun

    @ben: no donate page. just happy people find it useful!

  • http://www.fast2car.com ????????

    Oh so easy to use top. I use it here http://www.fast2car.com Open donation, I will support.

  • JIT

    Really Excellent Work….. :* saved lots of time :)

  • http://www.bizidea.co.th ?????????????

    try this: $('li.shuffle').shuffle();

    ?????????????

  • Pingback: Alex Barber | Digital Artist | jQuery Shuffle plugin

  • Mike

    Thanks for this – using it to randomize the presentation of images for a web-based experiment.

  • http://www.kooncar.com/ kooncar

    ahhhh….everything is code. actually i do not good at in code writing. but thanks for sharing yu useful information.

  • http://www.templatejuice.com J.F. Herrera

    Great work. I could not believe it was so easy.

  • http://scottrozman.net Scott Rozman

    Thanks! This was just what I needed.

    A note that may help someone else… I was running a few other jQuery plugins on the same page and was using jQuery.noConflict() on them. This plugin still conflicted with another one that was using noConflict until I had noConflict on both of them.

  • Pingback: Elegant D » jQuery: Shuffle Plugin | Yelotofu

  • ericbienfeo

    Is it possible to add a callback to the plugin so I'd know when it's done shuffling? Something like:

    $('ul.shuffle>li').shuffle(function(){
    console.log('Shuffle is done!')
    });

  • http://www.okcartv.com okcartv

    Thanks so much for the great script.

  • Pingback: jQuery?????????????????jQuery Shuffle Plugin? | Web????