1

考虑以下标记:

<div id="elements1">
    <div>Item 1</div>
    <div>Item 2</div>
    <div>Item 3</div>
    <div>Item 4</div>
    <div>Item 5</div>
</div>
<br/>
<ul id="elements2">
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
    <li>Item 5</li>
</ul>

我想生成这两个列表都将使用的随机顺序。因此,所需的输出可能如下所示:

<div id="elements1">
    <div>Item 2</div>
    <div>Item 5</div>
    <div>Item 3</div>
    <div>Item 1</div>
    <div>Item 4</div>
</div>
<br/>
<ul id="elements2">
    <li>Item 2</li>
    <li>Item 5</li>
    <li>Item 3</li>
    <li>Item 1</li>
    <li>Item 4</li>
</ul>

#elements1将永远有相同数量的孩子,#elements2反之亦然。

我的伪代码如下所示:

// see how many child elements in #elements1
// create order array based on # of child elements in i.e. [1,2,3,4,5]
// randomize array
// use order array to reorder both #elements1 and #elements2
// .appendTo() respective parents

我的策略看起来对手头的任务有效吗?(我会在一分钟内生成工作代码。)如果没有,有什么更好的方法来解决这个问题?谢谢你的帮助!

编辑:这是一个可以解决的问题。

4

3 回答 3

2

一种简单的方法是为此使用documentFragment

// lists with equal length
var list1 = document.getElementById('elements1');
var list2 = document.getElementById('elements2');
// a place to stash the items while randomizing
var stash1 = document.createDocumentFragment();
var stash2 = document.createDocumentFragment();

// initial length
var length = list1.childNodes.length;

// choose the same random child from the lists
// put them in their stashes preserving the new order
while(length > 0){
    var random = Math.floor((Math.random()*--length));
    stash1.appendChild(list1.childNodes[random]);
    stash2.appendChild(list2.childNodes[random]);
}

// put the elements back in the lists when done
list1.appendChild(stash1);
list2.appendChild(stash2);

演示:http: //jsfiddle.net/louisbros/NPPpt/

于 2013-05-06T23:07:58.920 回答
1

您可以使用已对第一个集合进行排序的值数组对第二个选定元素数组进行排序。

// selecting elements
var $elem1 = $('#elements1 div'),
    $elem2 = $('#elements2 li');

// cloning elements (for reordering)
var $ordered1 = $elem1.clone(),
    $ordered2 = $elem2.clone();

// randomizing elements
var helper = [],
    i = -1,
    $randomized1 = $elem1.sort(function () {
        var n = 0.5 - Math.random();
        helper.push(n);
        return n;
    }),
    $randomized2 = $elem2.sort(function () {
        return helper[++i];
    });

// .appendTo() respective parents
$('#elements1').append($randomized1);
$('#elements2').append($randomized2);

http://jsfiddle.net/zGLZG/

于 2013-05-06T22:45:21.460 回答
1

要简单地随机化Array的顺序,您可以执行以下操作

function shuffleArray(a) { // Fisher-Yates shuffle
    var i = a.length, t, j;
    while (--i) { // loop over each item in array (except 0 because no point)
        j = (Math.random() * (i+1)) | 0; // random Int j <= i
        t = a[i], a[i] = a[j], a[j] = t; // swap items i and j
    }
}

您需要将HTMLCollection转换为非实时内容,以便您可以更轻松地使用它,例如使用

elements1 = document.getElementById('elements1'); // cache for later
nodes1 = Array.prototype.slice.call(elements1.children); // children to Array

elements2 = document.getElementById('elements2');
nodes2 = Array.prototype.slice.call(elements2.children);

现在对于你真正想要随机化的东西(如果你不想修改上面的函数来同时打乱两个数组,见下文)

i = nodes1.length, a = new Array(i);
while (i--) a[i] = i;
// a = [0, 1, 2, 3, ...]

现在简单地随机a化,并按照新的数字顺序重新附加节点

shuffleArray(a); // a = e.g. [4, 8, 2, 5, ...]
for (i = 0; i < nodes1.length; ++i) {
    elements1.appendChild(nodes1[a[i]]); // append in new order
    elements2.appendChild(nodes2[a[i]]);
}

演示。我忽略var了,但记得在适用的情况下使用它。


决定为 2 Arrays添加 shuffle 的修改版本,因为这很可能会快得多。

function shuffleTwoArrays(a, b) { // Shuffle 2 arrays same length in same way
    var i = a.length, t, j;
    while (--i) { // loop over each item in array (except 0 because no point)
        j = (Math.random() * (i+1)) | 0; // random Int j <= i
        t = a[i], a[i] = a[j], a[j] = t; // swap items i and j in a
        t = b[i], b[i] = b[j], b[j] = t; // swap items i and j in b
    }
}

在这里你会做

shuffleTwoArrays(nodes1, nodes2); // shuffle both the same
for (i = 0; i < nodes1.length; ++i) {
    elements1.appendChild(nodes1[i]); // re-append to achieve new order
    elements2.appendChild(nodes2[i]);
}

演示

于 2013-05-06T22:45:48.897 回答