鍍金池/ 問答/HTML/ jQuery如何實現已上樹的dom元素隨機排序?

jQuery如何實現已上樹的dom元素隨機排序?

<div class="game-box">
    <p class="no1">1</p>
    <p class="no2">2</p>
    <p class="no3">3</p>
    <p class="no4">4</p>
    <p class="no5">5</p>
    <p class="no6">6</p>
    <p class="no7">7</p>
    <p class="no8">8</p>
    <p class="no9">9</p>
    <p class="no10">10</p>
    <div></div>
    <p class="no1">1</p>
    <p class="no2">2</p>
    <p class="no3">3</p>
    <p class="no4">4</p>
    <p class="no5">5</p>
    <p class="no6">6</p>
    <p class="no7">7</p>
    <p class="no8">8</p>
    <p class="no9">9</p>
    <p class="no10">10</p>
</div>

上面的代碼,目前p標簽在game-box中是固定順序排列的,我想實現每次刷新頁面p的排列順序都不一樣,尤其是開頭和結尾。目前我找到了一種不太好的方法,但是第一個元素經常不是9就是10,和我要的不一樣。

//這個方法不夠好
$(".game-box p").each(function(){
    if(Math.random() <= 0.5){
        $(this).prependTo($(this).parent());            
    }
})

請問有沒有更好的思路呢?
如果是下面的table tr td應該怎么做呢?

<table>
    <tr>
        <td class="bug1">1</td>
        <td class="bug2">2</td>
        <td class="bug3">3</td>
    </tr>
    <tr>
        <td class="bug4">4</td>
        <td class="bug5">5</td>
        <td class="bug6">6</td>
        <td class="bug7">7</td>
        <td class="bug8">8</td>
    </tr>
    <tr>
        <td class="bug9">9</td>
        <td class="bug10">10</td>
        <td class="bug11">11</td>
        <td class="bug12">12</td>
        <td class="bug13">13</td>
        <td class="bug14">14</td>
        <td class="bug15">15</td>
    </tr>
</table>
回答
編輯回答
夏夕

就是普通的對數組重排吧。。

2017年2月5日 19:32
編輯回答
風畔

核心邏輯,所有的節(jié)點重插一遍,但是插的位置是隨機數

window.onload = function() {
    $(".game-box p").toArray().forEach(function(node) {
        let length = $(".game-box p").length,
            randNumPos = parseInt(Math.random() * (length - 2));
        //所有的節(jié)點重插一遍,但是插的位置是隨機數
        $(".game-box").get(0).insertBefore(node, this.children[randNumPos]);
    });
};
2018年4月1日 13:13
編輯回答
故林

給你用原生寫了,保證比jq效率高,你可以適當替換成jq
(突然想起appendChild已有元素不需要先removeChild,把removeChild去掉了)

<div class="game-box">
    <p class="no1">1</p>
    <p class="no2">2</p>
    <p class="no3">3</p>
    <p class="no4">4</p>
    <p class="no5">5</p>
    <p class="no6">6</p>
    <p class="no7">7</p>
    <p class="no8">8</p>
    <p class="no9">9</p>
    <p class="no10">10</p>
</div>

<script>
function randomElms(parent) {
    // 獲取子元素合集
    let childrens = parent.children;

    // 確保只有一次重繪增加效率
    parent.style.display = 'none';

    for (
        // i取長度+1,設合集長度為10,i為11
        let i = childrens.length + 1;

        // 每次循環(huán),有序元素長度-1
        // 第一次遍歷時 --i 后 i為10
        // 隨機數范圍是[0,10),即 0 <= i < 10,向下取整后為[0,9]
        --i;

        // 從有序的子元素中隨機抽一個插到最后,保證亂序隨機性相同
        parent.appendChild(
            childrens[Math.random() * i >> 0]
        )
    );

    // 還原display
    parent.style.display = '';

    return parent;
}

// 獲取 .game-box 元素合集
let box = document.getElementsByClassName('game-box');
// 為每個 .game-box 單獨排序(不知道你會不會有多個 .game-box)
[].forEach.bind(box)(function(item) {
    randomElms(item);
});
</script>

table也是同樣的操作

<table>
    <tr>
        <td class="bug1">1</td>
        <td class="bug2">2</td>
        <td class="bug3">3</td>
    </tr>
    <tr>
        <td class="bug4">4</td>
        <td class="bug5">5</td>
        <td class="bug6">6</td>
        <td class="bug7">7</td>
        <td class="bug8">8</td>
    </tr>
    <tr>
        <td class="bug9">9</td>
        <td class="bug10">10</td>
        <td class="bug11">11</td>
        <td class="bug12">12</td>
        <td class="bug13">13</td>
        <td class="bug14">14</td>
        <td class="bug15">15</td>
    </tr>
</table>

<script>
function randomElms(parent) {
    let childrens = parent.children;
    parent.style.display = 'none';
    for (let i = childrens.length + 1; --i; parent.appendChild(childrens[Math.random() * i >> 0]));
    parent.style.display = '';
    return parent;
}

// 獲取 tr 合集
let trs = document.getElementsByTagName('tr');
// 給每個 tr 亂序
[].forEach.bind(trs)(function(item) {
    randomElms(item);
});
</script>
2017年2月5日 04:13
編輯回答
何蘇葉
$(".game-box").html(Array.prototype.sort.call($(".game-box p"), function () {
    return Math.random() - 0.5;
}))
2017年8月26日 14:50
編輯回答
汐顏
<div class="game-box">
    <p class="no1">1</p>
    <p class="no2">2</p>
    <p class="no3">3</p>
    <p class="no4">4</p>
    <p class="no5">5</p>
    <p class="no6">6</p>
    <p class="no7">7</p>
    <p class="no8">8</p>
    <p class="no9">9</p>
    <p class="no10">10</p>
    <div></div>
    <p class="no1">1</p>
    <p class="no2">2</p>
    <p class="no3">3</p>
    <p class="no4">4</p>
    <p class="no5">5</p>
    <p class="no6">6</p>
    <p class="no7">7</p>
    <p class="no8">8</p>
    <p class="no9">9</p>
    <p class="no10">10</p>
</div>
<script>
var $_gameBox = $('.game-box'),
a = $('.game-box > p').toArray();
while (a.length) $_gameBox.prepend(a.splice(~~(Math.random() * a.length), 1)[0]);
</script>
2017年11月13日 21:30
編輯回答
替身
// 獲取DOM元素
var $game_box = $('.game-box'),
    $game_box_list = $('.game-box p');

// 列表亂序后添加到game_box
$game_box.html(arrayRandomSort($game_box_list));

// 數據亂序方法
function arrayRandomSort(array) {
    var index = array.length;
    //開始遍歷
    for (var i = array.length; i > 0; i--) {
        var random = parseInt(Math.random() * index);
        index--;
        //交換位置
        var last = array[index];
        array[index] = array[random];
        array[random] = last;
    }
    return array;
}

我的思路是,把獲取到的DOM數組亂序后再放到game-box下。


// 獲取DOM元素
var $table = $('table'),
    $tr_list = $('table tr'),
    $td_list = $('table tr td');

// 生成亂序的td列表
var random_list = arrayRandomSort($td_list);

// 獲取每一行的td數量
var row_count = [];
$tr_list.each((i, el) => {
    row_count.push($(el).find('td').length);
});

// 根據每一行td的數量顯示
$tr_list.each((i, el) => {
    $(el).html(random_list.splice(0, row_count[i]));
});

// 數據亂序方法
function arrayRandomSort(array) {
    var index = array.length;
    //開始遍歷
    for (var i = array.length; i > 0; i--) {
        var random = parseInt(Math.random() * index);
        index--;
        //交換位置
        var last = array[index];
        array[index] = array[random];
        array[random] = last;
    }
    return array;
}

這個應該就是你想要的效果

2017年4月18日 08:53