While working on a new JavaScript mockup I needed a way to obtain a random jQuery item. While I could use jQuery(“selector”).get(int) to get a random item, I wanted to have a cleaner way of doing that to keep my code clean.
jQuery ships with great support for extensibility. You can not only extend jQuery with custom functions but filters as well. That is when I thought of the custom “:random” filter, just as you have the standard “:first”, “:last” and “:nth” filters.
Is jQuery capable of returning a random item?
While trying to get the “:random” filter working I’ve stumbled upon a challenge which kept making it all done impossible. As far as my understanding of the jQuery framework goes, it first selects all items based on the selector and then fires the logic defined at the filter to determine whether the particular item should be included in the returned match or not.
As far as I can tell the filter logic is being fired for each match and is supposed to return false if the match should be skipped and true if it should be included in the result. The problematic part here is “fired for each match”: as we are supposed to return a random item we should have one random number and then return only the item of which index is equal to the random number. Because the filter logic is fired for every item you would get a different random number at every run which could result in three scenarios:
- it might actually work and you would get exactly one item
- the filter would return multiple items, eg. random number 0 for the first item and 2 for third.
- the filter would return an empty array: eg. random number 3 for the first item and 0 for the last
The higher the number of matches the smaller the chance for scenario a as the routine for generating random number would be called more often.
Eventually I came with the following solution:
jQuery.jQueryRandom = 0;
jQuery.extend(jQuery.expr[":"],
{
random: function(a, i, m, r) {
if (i == 0) {
jQuery.jQueryRandom = Math.floor(Math.random() * r.length);
};
return i == jQuery.jQueryRandom;
}
});
Each time jQuery calls the “:random” filter the logic is being fired. The i parameter holds the index of the match returned by the selector. If it’s the first element in the match the random number will be generated and stored in the jQueryRandom variable. The random number is being generated based on the total number of matches returned by the selector which can be read from the r parameter. The rest is easy: if the index of the current item is equal to the random number, the current item should be included in the results.
You can use the “:random” filter as follows:
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
<script type="text/javascript">
$().ready(function() {
alert($("li:random").text());
});
</script>
Enjoy!




July 15th, 2009 at 4:37 pm
Explendid. Very simple and useful.
Thanks
July 15th, 2009 at 5:10 pm
It seems to not be working on any IE.
r.length returns the element\'s text string length (246, for example), not the number of elements. On any other browser, it returns correctly.
August 14th, 2009 at 8:19 pm
I'm wondering how you would use this script for the following:
Have random quotes on a page (li list). You would have the list but jQuery positions/reorders them randomly for each time the page refreshes?
Any ideas?
August 15th, 2009 at 8:42 am
@e11world: to be honest I would create new code to do the job. Instead of retrieving the separate li items using the :random filter I would retrieve the whole list at once, and then do the shuffling.
August 16th, 2009 at 10:28 am
@Alexandre de Oliveira: it took a while, but I've just tested it in IE8 and it works perfectly. Could you provide any more details about your scenario?
December 6th, 2009 at 9:14 pm
Thank you for the awesome snippet of code! I'm currently working on a for-fun project making a story engine similar to text adventure games, and have been looking for good ways to randomize and limit options, and this will work perfectly!
January 4th, 2010 at 10:38 pm
Hi, thanks for the snippet it works fine but I'm getting same error that Alexandre de Oliveira in IE(8)
please, you can fixed it?
thank you!
January 5th, 2010 at 6:32 am
@keo: could you provide some more information on how you're using it (eg. what is your HTML and what is your selector)?
March 28th, 2010 at 11:46 pm
[...] much liking this little bit of jquery code for random selections. http://blog.mastykarz.nl/jquery-random-filter/ [...]
April 19th, 2010 at 6:38 pm
Great snippet.
For some reason I had to change my query slightly from:
$("#section1 .links a:random")
To:
$("#section1 .links").find("a:random").
r.length was considerably higher than it should have been in the first case, but the second selector worked fine.
Thoughts?
July 7th, 2010 at 8:07 pm
Can you provide any additional insight regarding using this snippet to display list items (li) in a random order?
Many thanks for your work!
July 8th, 2010 at 5:01 am
@Renee: the script I showed you allows you to pick a random item, not shuffle list items in a random order. I think you would need a whole different script for your scenario. Have you already tried looking up the jQuery plugins gallery?
September 7th, 2010 at 10:57 am
I used it for a random starting carousel using sorgalla.com Jcarousel. Thank you very much, here is the example code:
$(".banner_carousel").jcarousel({
auto:6,
start:$.random($(".banner_carousel li").size()),
scroll:2,
wrap: 'circular'
});
September 7th, 2010 at 10:59 am
Sorry using this one:
jQuery.extend({
random: function(X) {
return Math.floor(X * (Math.random() % 1));
},
randomBetween: function(MinV, MaxV) {
return MinV + jQuery.random(MaxV – MinV + 1);
}
});
September 15th, 2010 at 10:25 pm
This also is proving buggy for me in IE8+.
Wonder why?
September 15th, 2010 at 10:40 pm
let me just follow up on that. It looks like this happens in compatibility mode – so IE7-. When I check out r.length it is way off pre IE8. Wonder if anyone has noticed anything similar?
October 11th, 2010 at 1:52 am
I too have had up and down results with both IE7 and IE8 using this filter. My only guess is that IE is randomly selecting some kind of empty node assuming its an element and the rest is history.
One time I fixed it by helping the filter by identifying both the element's parent and its type:
$('#parentElm div.someElmClass:random').show();
Sometimes however, this also fails to kick IE into gear. Any insight?
January 24th, 2011 at 7:36 pm
[...] a bit messy and performs too many tasks and permutations for me to be satisfied. Another one is the :random filter, but that only selects one element. There is also a nice little jquery.shuffle.js that [...]
March 14th, 2011 at 3:37 am
Cool thanks for sharing! This might not work for all purposes as afEkenholm politely points out…there's a good discussion on it here:
http://stackoverflow.com/questions/962802/is-it-correct-to-use-javascript-array-sort-method-for-shuffling
June 29th, 2011 at 3:14 pm
[...] a new function to the $.expr[':'] object. One awesome use case was presented by Waldek Mastykarz on his blog: creating a selector for retrieving a random element. You can see a slightly modified version of [...]
June 29th, 2011 at 3:14 pm
[...] a new function to the $.expr[':'] object. One awesome use case was presented by Waldek Mastykarz on his blog: creating a selector for retrieving a random element. You can see a slightly modified version of [...]
July 4th, 2011 at 5:32 pm
what are the arguments to that function? you explained 2 of them but could you let me know what the other two are for? thanks a lot, great work!
July 4th, 2011 at 6:49 pm
@Kirn: those are standard parameters that jQuery passes to its filters. See jQuery documentation for more details.
July 4th, 2011 at 7:47 pm
[...] function to the $.expr[':'] object. One awesome use case was presented by Waldek Mastykarz on his blog: creating a selector for retrieving a random element. You can see a slightly modified version of [...]
July 5th, 2011 at 9:05 am
[...] new function to the $ .expr[':'] object. One awesome use case was presented by Waldek Mastykarz on his blog: creating a selector for retrieving a random element. You can see a slightly modified version of [...]
July 25th, 2011 at 5:21 am
Phillip, I'm curious how you using this with jCarousel. I put in your scripts and it didn't work… is there another element you had to write somewhere else? Or something else you had to take out?
thanks
July 25th, 2011 at 4:00 pm
I used the JQUERY.RAND() method:
see http://www.labs.skengdon.com/rand
July 25th, 2011 at 9:44 pm
Hi Phillip- thanks for your answer. Sorry to be a dope, but in which file and where do you place that code? I'm just getting started with jquery.
Thanks.
July 26th, 2011 at 8:05 am
Simple just call the random from the callback:
$(".banner_carousel").jcarousel({
auto:6,
start:$.random($(".banner_carousel li").size()) // <— HERE!
,scroll:2,
wrap: 'circular'
});
August 14th, 2011 at 12:27 pm
[...] a new function to the $.expr[':'] object. One awesome use case was presented by Waldek Mastykarz on his blog: creating a selector for retrieving a random element. You can see a slightly modified version of [...]
September 6th, 2011 at 9:56 am
[...] a new function to the $.expr[':'] object. One awesome use case was presented by Waldek Mastykarz on his blog: creating a selector for retrieving a random element. You can see a slightly modified version of [...]
September 18th, 2011 at 6:02 pm
[...] eu estava navegando em um site bem legal, quando encontrei um código muito simples, porem extremamente útil em diversas [...]
October 6th, 2011 at 2:48 pm
[...] function to the $.expr[':'] object. One awesome use case was presented by Waldek Mastykarz on his blog: creating a selector for retrieving a random element. You can see a slightly modified version of [...]
October 7th, 2011 at 12:34 am
[...] a new function to the $.expr[':'] object. One awesome use case was presented by Waldek Mastykarz on his blog: creating a selector for retrieving a random element. You can see a slightly modified version of [...]
November 17th, 2011 at 7:27 am
[...] to add a new method to the $. Expr [':'] object. A great way to Waldek Mastykarz use the blog mentioned: Create a random element to return selector. You can modify the following [...]
December 21st, 2011 at 3:31 am
[...] 上面我提到过,jQuery添加它自己的选择器过滤。除了类库,你可以添加自己的过滤器。只需要添加一个新的方法到$.expr[':']对象。一个非常棒的使用方式是Waldek Mastykarz的博客中提到的:创建一个用来返回随机元素的选择器。你可以修改下面代码: [...]
February 18th, 2012 at 6:36 am
[...] function to the $.expr[':'] object. One awesome use case was presented by Waldek Mastykarz on his blog: creating a selector for retrieving a random element. You can see a slightly modified version of [...]
February 18th, 2012 at 7:00 am
[...] function to the $.expr[':'] object. One awesome use case was presented by Waldek Mastykarz on his blog: creating a selector for retrieving a random element. You can see a slightly modified version of [...]
February 21st, 2012 at 5:19 am
I ran into the same problem as Allain — the filter doesn't work if you qualify the element with a parent selector. For example, $("ul.foo li:random") will select ANY list item, not just the ones in the "foo" list. His workaround avoids the problem.
April 7th, 2012 at 5:23 am
[...] a new function to the $.expr[':'] object. One awesome use case was presented by Waldek Mastykarz on his blog: creating a selector for retrieving a random element. You can see a slightly modified version of [...]
May 9th, 2012 at 10:04 pm
[...] применения был представлен Уолдеком Мастикарзем в его блоге: создание селектора для получения случайного [...]
June 7th, 2012 at 9:33 am
Worked fine for me in IE9. Haven't tried IE8 yet.
Very cool little filter.
Used it to help randomize img ordering for a filmstrip of photo's
July 3rd, 2012 at 8:37 pm
[...] a new function to the $.expr[':'] object. One awesome use case was presented by Waldek Mastykarz on his blog: creating a selector for retrieving a random element. You can see a slightly modified version of [...]
October 9th, 2012 at 9:44 am
[...] function to the $.expr[':'] object. One awesome use case was presented by Waldek Mastykarz on his blog: creating a selector for retrieving a random element. You can see a slightly modified version of [...]
October 29th, 2012 at 2:15 am
[...] Mastykarz的博客中提到的:创建一个用来返回随机元素的选择器。你可以修改下面代码: [...]
March 6th, 2013 at 12:06 am
[...] a new function to the $.expr[':'] object. One awesome use case was presented by Waldek Mastykarz on his blog: creating a selector for retrieving a random element. You can see a slightly modified version of [...]