views:

1477

answers:

7

I'm relatively new to Javascript and was wondering if there's a quick way to shuffle content that is contained in multiple <div> tags. For example

<div id='d1'>
  <span>alpha</span>
  <img src='alpha.jpg'>
</div>
<div id='d2'>
  <span>beta</span>
  <img src='beta.jpg'>
</div>
<div id='d3'>
  <span>gamma</span>
  <img src='gamma.jpg'>
</div>

<button onclick='shuffle_content();'>Shuffle</button>

After clicking on the button, I'd like the content in d1, d2, d3 to change places (for example maybe d3 would be first, then d1, then d2).

A quick way to kind of move things around is to copy the first div element (d1), then put it at the very end (after d3), and then delete the original d1. But that doesn't really randomize things. It just makes things go in the cycle (which might be ok).

Any suggestions would be appreciated. Thanks.

A: 

I'd wrap the divs in an outer div, then pass its id to shuffle_content().

In there, you could create a new div, cloning the wrapper div's nodes in a random order to fill it, then replace the wrapper div with the new div.

Kev
A: 

I would suggest you randomize the content, not the actual Divs themselves. You could accomplish this by putting the content in separate html pages - no header info or body, just the content.

Then use a function on page load to randomly assign which div gets what content and use this to change the DIV's content:

<script type="text/javascript">
    function ajaxManager(){
        var args = ajaxManager.arguments;

        if (document.getElementById) {
            var x = (window.ActiveXObject) ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
        }
        if (x){         
            switch (args[0]){
                case "load_page":
                    if (x)
                    {
                        x.onreadystatechange = function()
                        {
                            if (x.readyState == 4 && x.status == 200){
                                el = document.getElementById(args[2]);
                                el.innerHTML = x.responseText;
                            }
                        }
                        x.open("GET", args[1], true);
                        x.send(null);
                    }
                    break;

                case "random_content":
                    ajaxManager('load_page', args[1], args[2]); /* args[1] is the content page, args[2] is the id of the div you want to populate with it. */       
                    break;
            } //END SWITCH
        } //END if(x)
    } //END AjaxManager

</script>
Rob Allen
This doesn't answer the question, just explains a different way to move the content.
Joel Anair
I offered a quick way to move the content around which is the OP's original intent. What did you read the question to ask?
Rob Allen
A: 

I'd use server side code to accomplish this. I know this isn't really an answer to your question, but it is an alternative implementation.

Best Regards,
Frank

Frank V
+3  A: 

are you ok with using a javascript library like jQuery? here's a quick jQuery example to accomplish what you're after. the only modification to your HTML is the addition of a container element as suggested:

<div id="shuffle">
    <div id='d1'>...</div>
    <div id='d2'>...</div>
    <div id='d3'>...</div>
</div>

and javascript:

function shuffle(e) {               // pass the divs to the function
    var replace = $('<div>');
    var size = e.size();

    while (size >= 1) {
       var rand = Math.floor(Math.random() * size);
       var temp = e.get(rand);      // grab a random div from our set
       replace.append(temp);        // add the selected div to our new set
       e = e.not(temp); // remove our selected div from the main set
       size--;
    }
    $('#shuffle').html(replace.html() );     // update our container div with the
                                             // new, randomized divs
}

shuffle( $('#shuffle div') );
Owen
Thanks Owen, I think this is best answer I've seen so far.
Chris
Unfortunately, since my reputation is below 15, I can't vote this up. But if I could, I would.
Chris
+1  A: 

You can grab the content of each div

c1 = document.getElementById('div1').innerHTML
c2 = document.getElementById('div2').innerHTML
c3 = document.getElementById('div3').innerHTML

Then determine a new order for them randomly .. and then put each content in the new destination

say for instance, the randomness gave:

c1_div = 'div2'
c2_div = 'div1'
c3_div = 'div3'

then you just:

document.getElementById(c1_div).innerHTML = c1
document.getElementById(c2_div).innerHTML = c2
document.getElementById(c3_div).innerHTML = c3
hasen j
This is also a good answer. Thanks Hasen.
Chris
A: 

For your HTML, the short answer to your question is:

function shuffle_content() {
 var divA = new Array(3);
 for(var i=0; i < 3; i++) {
  divA[i] = document.getElementById('d'+(i+1));
  document.body.removeChild(divA[i]);
 }
 while (divA.length > 0)
  document.body.appendChild(divA.splice(Math.floor(Math.random() * divA.length),1)[0]);
}

To get there I wrote the following, which I think works better:

<html>
<div id="cards">
<div id="card0">Card0</div><div id="card1">Card1</div>
<div id="card2">Card2</div><div id="card3">Card3</div>
<div id="card4">Card4</div><div id="card5">Card5</div>
<div id="card6">Card6</div><div id="card7">Card7</div>
<div id="card8">Card8</div><div id="card9">Card9</div>
</div>
<button id="shuffle">Shuffle</button>
<script language="javascript">
<!--
document.getElementById('shuffle').onclick = function () {
var divCards = document.getElementById('cards');
var divCardsArray = new Array(
    document.getElementById('card0'),
    document.getElementById('card1'),
    document.getElementById('card2'),
    document.getElementById('card3'),
    document.getElementById('card4'),
    document.getElementById('card5'),
    document.getElementById('card6'),
    document.getElementById('card7'),
    document.getElementById('card8'),
    document.getElementById('card9')
    );
return function() {
    var mDivCardsArray=divCardsArray.slice();
    while (divCards.childNodes.length > 0) {
     divCards.removeChild(divCards.firstChild);
    }
    while (mDivCardsArray.length > 0) {
     var i = Math.floor(Math.random() * mDivCardsArray.length);
     divCards.appendChild(mDivCardsArray[i]);
     mDivCardsArray.splice(i,1);
    }
    return false;
}
}()
//-->
</script>
</html>

I was trying to pack down that last while statement to:

    while (mDivCardsArray.length > 0) {
     divCards.appendChild(
      mDivCardsArray.splice(
       Math.floor(Math.random() * mDivCardsArray.length)
       ,1)[0]
     );
    }

but this is pretty hard to read and prone to error.

Going with jQuery or Prototype you could follow the same basic structure and get the result you're looking for.

Personally, I think it looks even better if you add 2 more divs to the cards stack, expand the divCardsArray, insert the following style block, and add this code right after the divCardsArray definition.

<html>
...
<style>
html,body{height:100%;width:100%;text-align:center;font-family:sans-serif;}
#cards,#cards div{padding:5px;margin:5px auto 5px auto;width:100px;}
</style>
...
<div id="cardA">CardA</div><div id="cardB">CardB</div>
...
var colorCardsArray = new Array(
    '#f00', '#f80', '#ff0', '#8f0', '#0f0', '#0f8',
    '#0ff', '#08f', '#00f', '#80f', '#f0f', '#f08' );
for(var i=0;i<divCardsArray.length;i++)
    divCardsArray[i].style.backgroundColor=colorCardsArray[i];
...
</html>
dlamblin
A: 

I tried the suggestion from Owen, but does not work for me.

The page body looks like this:

     <div id="leftColumn">  
    <div id="thumbnailHolder">
    <div id="pinkTabHolder">
    <div id="pinkTab"><span></span></div>
        </div>

<div class="one"><a href="sdfs.html"><img src="images/small/test.jpg" alt="dsfsdfsdfd" title="" /></a> </div>

<div class="two"><a href="/photographs/wfh"><img src="images/small/wfh.jpg" alt="Willem FH" title="" /></a></div>

<div class="tree"><a href="/art/last-one"><img src="images/small/h29.jpg" alt="Last" title="" /></a></div>

I include the javascript in the head <script type="text/javascript" src="java/shuffle.js"></script>

Where should I insert the <div id="shuffle"> for it to work? Am I supposed to edit the javascript?

Jerome