1

I am using the Colorbox Lightbox script to call a hidden div on a page. It works great but there is a catch. I have 15 hidden divs. When a link is clicked I would like a new lightbox to show each time without repeating until all have been shown. I do not know how to do this.

Here is my code to call the lightbox:

$(".colorbox").colorbox({
    inline:true 
});

Here is the HTML of the hidden divs

<div class="hide">
 <div id="lightbox1">
    <!-- Content --> 
 </div>
 <div id="lightbox2">
    <!-- Content --> 
 </div>
 <!-- etc -->
</div>

How would I call each div at random until all have been shown then start over?

Also is there a way that once divs 1 - 15 have been shown to then show one last div (id="last-div") before restarting?

Note: All divs would be called on a click and I am using jQuery 1.8.2.

I do not know where to start, I have seen scripts using Math.random() but I do not understand enough to make that work.

UPDATE

I have tried Ian's answer but the lightbox is not showing (but I can see in the console log that the script is working)

Originally he has this in his script:

$(selector).show();

which I changed to this:

$(selector).colorbox({inline:true });

What do I need to do to call the lightbox?

Note: No errors are thrown.

L84
  • 45,514
  • 58
  • 177
  • 257
  • I think you misunderstand how to use the `colorbox` constructor. When you use `$(selector).colorbox`, it binds a `click` event (behind the scenes) so that when you click on `selector`, it opens up a lightbox based on the options - in this case `{inline: true}`, which means it looks for the element that is specified in the `href` of the element clicked. At least I think that's how it works. – Ian Oct 31 '12 at 07:22
  • @Ian - Okay, I think I follow. How would I change to trigger the colorbox lightbox? Sorry for my ignorance and thanks for your help! – L84 Oct 31 '12 at 07:25
  • To make it dynamic, you may need to use the more general colorbox call `$.colorbox` which means it should open immediately. I think this might work: `$.colorbox({html: $(selector).html()});` – Ian Oct 31 '12 at 07:26
  • No problem! I was trying to read the colorbox docs and figure it out as you commented. If that solution even works, I'm not sure it's efficient/good at all! – Ian Oct 31 '12 at 07:27

3 Answers3

3

So my idea was similar to Eric's, but I wanted to make it work "completely". So instead of storing references to all the divs in an array, I just decided to store an array of ints representing each div. The way I eventually select them with jQuery is "#lightbox + i", so if you don't have this exact structure (where the divs have an id like "lightbox" and an int - from 1 to the last count), then you can use .eq() or nth-child. It won't be the exact same results, but it will have the same random effect, just done in a different way. I found a function that "randomizes" an array - I'm guessing like what Eric's Shuffle does. But here's where I got it from - How to randomize (shuffle) a JavaScript array? . I had to modify it to return a new array instead of modify the one passed to the function. Also, I kept everything in the document.ready scope, instead of the global scope, so things are passed/returned a lot. It worked fine before when I had all and randomed declared globally and didn't pass them around, I just thought this would be "better" since they weren't global.

Here's the fiddle:

http://jsfiddle.net/6qYCL/1/

And here's the Javascript:

$(document).ready(function () {
    var all,
        randomed;

    all = generateAll();
    randomed = generateRandomed(all);

    $("#generator").on("click", function (evt) {
        evt.preventDefault();
        randomed = doNext(all, randomed);
    });
});

function generateAll() {
    // Generates the array of "all" divs to work on
    var a = [];
    var divs = $(".hide > div.lightbox");
    for (var i = 1; i <= divs.length; i++) {
        a.push(i);
    }
    console.log("List of divs available to toggle: " + a);
    return a;
}

function generateRandomed(all) {
    // Randomizes the original array
    randomed = fisherYates(all);
    console.log("Setting randomized array: " + randomed);
    return randomed;
}

function doNext(all, randomed) {
    $(".lightbox, #last-div").hide();

    if (randomed.length < 1) {
        console.log("All lightboxes toggled, showing last, then starting over");
        $("#last-div").show();
        randomed = generateRandomed(all);
    } else {
        var next = randomed.shift();
        var selector = "#lightbox" + next;
        console.log("Showing " + selector);
        $(selector).show();
        console.log("What's left: " + randomed);
    }

    return randomed;
}

// Randomizes an array and returns the new one (doesn't modify original)
function fisherYates ( myArray ) {
  var return_arr = myArray.slice(0);
  var i = return_arr.length;
  if ( i == 0 ) return false;
  while ( --i ) {
     var j = Math.floor( Math.random() * ( i + 1 ) );
     var tempi = return_arr[i];
     var tempj = return_arr[j];
     return_arr[i] = tempj;
     return_arr[j] = tempi;
  }
  return return_arr;
}

It accounts for getting to the end of the list and display #new-div like you mentioned, then starting the process over. If you look in your browser's console, you can "watch" what's happening during initialization and when clicking the link.

I think this is close to what you were looking for. I'm not sure which is a better solution - storing references to the elements or just an array of ints to loop through and eventually find. I know there are many variations on how to do this - when/how to store the counting stuff, when/how to randomize the array or retrieve a random value (and how to keep track of which has been used), where to store all references, and plenty more. I hope this at least helps!

Community
  • 1
  • 1
Ian
  • 50,146
  • 13
  • 101
  • 111
  • Thanks and hopefully I can get this working! I attempted to add my lightbox code but it is not working! See my edit to the question for what I did. – L84 Oct 31 '12 at 07:11
  • Thanks for your help, it works!!! (With the help from your comments above => ) Thanks Again! – L84 Oct 31 '12 at 07:35
  • @Lynda Awesome, no problem! I'm just worried weird things may happen if you have any events bound in `$(selector).html()` but that may be silly to worry about. Just keep testing it and make sure everything works fine. If it's normal HTML, I'm sure it'll be fine. Hope it continues to work out! – Ian Oct 31 '12 at 07:39
  • It works okay as far as I can tell on the page and I will be using this only on one page so I am not worried. Thanks Again! – L84 Oct 31 '12 at 07:44
  • 1
    One more thing - Make sure before this is on a live site to remove or comment out the `console.log` IE throws a fit and will not work without it. – L84 Oct 31 '12 at 09:40
  • @Lynda very true, or at least add logic to your website to check if console and console.log exists, and if not for either, add a filler for whichever that ends up doing nothing (just so the calls dont fail but you can keep the code) – Ian Oct 31 '12 at 18:13
2

Create an array of all of them, then shuffle that array, then pull the next one each time you get a click. When you run out, you can repopulate the array if necessary.

Something like this (using the Shuffle method from this source):

Fiddle

var array = $(".hide div").toArray(); // Add all divs within the hide div to an array
var randomArray = Shuffle(array); // Shuffle the array

$("a").click(function() {
    if (randomArray.length > 0)
        alert(randomArray.shift().innerHTML); // Show contents of div, as an example
    else
        alert("None left!");
    return false;
});
Cat
  • 66,919
  • 24
  • 133
  • 141
-1

The solution below works by passing an array of elements to a function. As each div is displayed it is taken out of the array. Then from the divs left in the array the next one is picked at random.

// call this function on page load
function begin( ) { 

    var arr = $(".hide div").toArray();   
    // further elements can be added to arr i.e. last-div 
    showDivs( arr.length, arr );
}   

// begin displaying divs
function showDivs( numberOfDivs, divArray ) {
    var i, lastDiv;

    function nextDiv( ) {

        // depending on number of slides left get random number
        i = randomInt( numberOfDivs ); 
        if( lastDiv ) { $(lastDiv).hide() };

        $( divArray[ i ] ).fadeIn( 3000 );

        // now that this div has been displayed
        // remove from array and cache
        lastDiv = divArray.splice( i, 1 );

        numberOfDivs--;

        // no more divs to display
        if( numberOfDivs == 0 ) { return };

        setTimeout( nextDiv, 4000);
    }

    setTimeout( nextDiv, 1000);

}

// calculate next random index
function randomInt( divsLeft ) {
   var i = Math.random() * divsLeft;
   return Math.round( i );
}

Fiddle here

Bruno
  • 5,772
  • 1
  • 26
  • 43