2

I've got a block of HTML that looks like this:

<div id="banners">
    <a href="p1.html"><img src="img1.jpg" /></a>
    <a href="p2.html"><img src="img2.jpg" /></a>
    <a href="p3.html"><img src="img3.jpg" /></a>
    <a href="p4.html"><img src="img4.jpg" /></a>
    <a href="p5.html"><img src="img5.jpg" /></a>
</div>

Using JavaScript, I'd like to randomly pick two of those images and their corresponding links and display them, while hiding the others. Also, they need to not be duplicates, meaning, I want to avoid showing something like img1.jpg img1.jpg at the same time.

jQuery is being used on the site, so it'd be nice if the proposed solution was a jQuery solution.

It's unfortunate that I don't have access to the backend of this site, or else I'd explore a server-side solution. It's just not possible in this instance.

ctrlaltdel
  • 685
  • 2
  • 10
  • 21

3 Answers3

7
var allBanners = $('#banners a');
allBanners.hide();

var index = Math.floor(Math.random() * allBanners.length);
allBanners.eq(index).show();

var index2 = Math.floor(Math.random() * allBanners.length - 1);
allBanners.not(allBanners.eq(index)).eq(index2).show();

Demo

David Hedlund
  • 128,221
  • 31
  • 203
  • 222
  • Hey, David I wonder if I want to display 5 of 10 images instead what should I do ? I have tried to edit your code but it does not work properly – Poramat Fin Nov 15 '13 at 14:40
  • More info: I want to display 5 image of 10. And not showing duplicate image. And the most important is each time i press button it must show 5 image. But After I edited your code by putting index3, index4, index5…After I press button 2-3 times it show only 4 images. Sometimes 3 images. What is wrong ? And how to fix this ? – Poramat Fin Nov 15 '13 at 15:28
  • @PoramatFin: yeah, this solution doesn't scale very neatly. To be able to extend it as it is, you'd need to have more and more `.not`s chained, and you'd need to decrement the randomization range (increasing the `-1` term) as you go, and as you do that, you'd have to counter for the fact that that operation will sometimes give you indexes lower than 0 (these would be the "misses" where you end up with less than 5 elements in your result). – David Hedlund Nov 15 '13 at 18:50
  • For your scenario, it'd be worth doing a proper shuffle [for instance, as described here](http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array) and then just grab the first slice of the result. [Demo](http://jsfiddle.net/QE6yK/) – David Hedlund Nov 15 '13 at 18:51
  • You ´re fantastic, Devid Hedlund :) One more think. I´m trying to call the function using document.ready methode. But it does not work why ? $(document).ready(function(randomize){ randomize(); }); – Poramat Fin Nov 18 '13 at 13:31
  • @PoramatFin: The `ready` listener accepts a function that may in itself accept one argument, which will be the jQuery object. This is for `noConflict` compatibility. With jQuery in `noConflict` mode, there is no `$` globally defined, but if you name the argument in your `ready` listener, you can still use it: `jQuery(document).ready(function($) { ... })`. You're naming that object `randomize`. This means that when you call `randomize()` in your code, that will not be a reference to the outside function, but to the jQuery object. Just write `$(document).ready(function() { randomize(); })` – David Hedlund Nov 18 '13 at 14:32
  • Or if you want, jQuery provides a shorthand for the DOMReady event, which means you can simply write `$(function() { ... })`. It is equivalent to `$(document).ready(function() { ... })`. Since the funciton you want to call on DOMReady requires no arguments on its own, you could use *that* as the listener, rather than have a listener call it: `$(randomize)` is equivalent of `$(document).ready(function() { randomize(); })` as long as `randomize` isn't using any arguments (as described above, *it* would be called with a reference to the jQuery object as the only argument). – David Hedlund Nov 18 '13 at 14:35
2
var elem = $("#banners a");
var img1 = Math.floor(Math.random() * elem.length), 
    img2 = Math.floor(Math.random() * elem.length);

while (img1===img2) {
  img2 = Math.floor(Math.random() * elem.length);
}

elem.hide();
elem.eq(img1).show();
elem.eq(img2).show();

FIDDLE

adeneo
  • 312,895
  • 29
  • 395
  • 388
1
$('a').hide();
var count = 0;
while(count < 2) {
var number = 1 + Math.floor(Math.random() * 5); 
if($('a[href="p' + number + '.html"]:visible').length == 0) {
 $('a[href="p' + number + '.html"]').show();
 count++;
}
}

This ensures the unbiased randomness over choosing those two images.

sundar
  • 1,760
  • 12
  • 28