7

我对 Javascript 比较陌生,想知道是否有一种快速的方法来随机播放包含在多个<div>标签中的内容。例如

<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>

单击按钮后,我希望 d1、d2、d3 中的内容更改位置(例如,可能首先是 d3,然后是 d1,然后是 d2)。

一种快速移动的方法是复制第一个 div 元素 (d1),然后将其放在最后(d3 之后),然后删除原始 d1。但这并没有真正随机化事情。它只是让事情进入循环(这可能没问题)。

任何建议,将不胜感激。谢谢。

4

8 回答 8

21

你可以使用像jQuery这样的 javascript 库吗?这是一个快速的 jQuery 示例来完成你所追求的。对 HTML 的唯一修改是按照建议添加容器元素:

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

和 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') );
于 2008-11-24T20:29:58.823 回答
19

最近的一个问题刚刚作为此问题的副本关闭,但我觉得我得到的答案比这里的任何问题都好。这个方法很直接。复制 HTML 并不麻烦,因此保留了对 DOM、样式、事件处理程序等的更改。

要打乱某个父元素的所有子元素,请选择一个随机子元素并将其一次附加回父元素,直到重新附加所有子元素。

使用 jQuery:

var parent = $("#shuffle");
var divs = parent.children();
while (divs.length) {
    parent.append(divs.splice(Math.floor(Math.random() * divs.length), 1)[0]);
}

演示:http: //jsfiddle.net/C6LPY/2

如果没有 jQuery,它是相似的,同样简单:

var parent = document.getElementById("shuffle");
var divs = parent.children;
var frag = document.createDocumentFragment();
while (divs.length) {
    frag.appendChild(divs[Math.floor(Math.random() * divs.length)]);
}
parent.appendChild(frag);

演示:http: //jsfiddle.net/C6LPY/5/



编辑: 这是代码的细分:

// Create a document fragment to hold the shuffled elements
var frag = document.createDocumentFragment();

// Loop until every element is moved out of the parent and into the document fragment
while (divs.length) {

    // select one random child element and move it into the document fragment
    frag.appendChild(divs[Math.floor(Math.random() * divs.length)]);
}

// appending the document fragment appends all the elements, in the shuffled order
parent.appendChild(frag);
于 2012-03-09T21:58:33.137 回答
2

你可以抓取每个div的内容

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

然后随机为它们确定一个新的顺序..然后将每个内容放入新的目的地

例如,随机性给出:

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

那么你只需:

document.getElementById(c1_div).innerHTML = c1
document.getElementById(c2_div).innerHTML = c2
document.getElementById(c3_div).innerHTML = c3
于 2008-11-24T20:35:15.303 回答
1

扩展@gilly3 的好答案,使用 jQuery 实际上可以避免divs在循环中附加随机选择的元素,而是通过随机sorting div代替并同时appending 全部:

$(function() {
  var parent = $("#shuffle");
  var divs = parent.children();
  divs.sort(function(a, b) {
    return 0.5 - Math.random();
  });
  parent.append(divs);
});

演示:http: //jsfiddle.net/ey70Lxhk/

但是请注意,这种技术在随机性方面并不准确,并且依赖于sort不随元素数量线性缩放的随机性。

于 2019-05-07T17:12:35.237 回答
0

我将 div 包装在外部 div 中,然后将其 id 传递给 shuffle_content()。

在那里,您可以创建一个新 div,以随机顺序克隆包装器 div 的节点以填充它,然后用新 div替换包装器 div。

于 2008-11-24T19:39:31.530 回答
0

我会使用服务器端代码来完成此操作。我知道这并不是您问题的真正答案,但它一种替代实现。

最好的问候,
弗兰克

于 2008-11-24T20:29:48.917 回答
0

对于您的 HTML,您的问题的简短回答是:

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]);
}

为了到达那里,我写了以下内容,我认为效果更好:

<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>

我试图将最后一个 while 语句打包为:

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

但这很难阅读并且容易出错。

使用 jQuery 或 Prototype,您可以遵循相同的基本结构并获得您正在寻找的结果。

cards就个人而言,我认为如果你在堆栈中再添加 2 个 div,展开divCardsArray,插入以下样式块,并在divCardsArray定义之后立即添加此代码,它看起来会更好。

<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>
于 2008-11-24T21:17:23.783 回答
-1

我建议您随机化内容,而不是实际的 Div 本身。您可以通过将内容放在单独的 html 页面中来实现这一点 - 没有标题信息或正文,只有内容。

然后在页面加载时使用一个函数来随机分配哪个 div 获取什么内容并使用它来更改 DIV 的内容:

<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>
于 2008-11-24T20:05:26.937 回答