首页 > 解决方案 > 如何从节点列表中随机重新渲染 DOM 节点的优先顺序?

问题描述

我试图通过重新排序我的节点索引来洗牌NodeList

如何实现删除和附加我拥有的类属性的子级?

HTML:

<div class="card" data-card="1" onclick="cardClicked(this)">
    <img src="img/cards/1.png" alt="">
    <img class="back" src="img/cards/back.png" alt="">
</div>

<div class="card" data-card="7" onclick="cardClicked(this)">
    <img src="img/cards/7.png" alt="">
    <img class="back" src="img/cards/back.png" alt="">
</div>

<div class="card" data-card="1" onclick="cardClicked(this)">
    <img src="img/cards/1.png" alt="">
    <img class="back" src="img/cards/back.png" alt="">
</div>

JavaScript:

function shuffleCards() {
    let cards = document.querySelectorAll('.card');
    let cardsArray = Array.from(cards);
    // reorder the nodes of the nodelist (cards)
}

标签: javascriptarraysdomshufflenodelist

解决方案


有几种方法可以“洗牌”数组。我在一个实验性的“战争”纸牌游戏中选择了 Fisher-Yates 方法。 https://github.com/scottm85/war/blob/master/src/Game/Deck.js#L80

shuffle()
{
    /* Use a Fisher-Yates shuffle...If provides a much more reliable shuffle than using variations of a sort method https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle */
    let cards = this.cards;
    for (let i = cards.length - 1; i > 0; i--)
    {
        let j = Math.floor(Math.random() * (i + 1)); // random index from 0 to i
        [cards[i], cards[j]] = [cards[j], cards[i]];
    }
    this.cards = cards;

    console.log("----------------- Deck Shuffled -----------------");
}

https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

当然,我提供的示例与您的需求略有不同,因为我在 react 中执行此操作,构建了一个 Deck 数组,并且没有使用 JS 进行直接 DOM 操作。但理论上,您可以修改它以使用您的方法。像这样的东西:

function shuffleCards
{
    let cards = document.querySelectorAll('.card');
    let cardsArray = Array.from(cards);

    for (let i = cardsArray.length - 1; i > 0; i--)
    {
        let j = Math.floor(Math.random() * (i + 1)); // random index from 0 to i
        [cardsArray[i], cardsArray[j]] = [cardsArray[j], cardsArray[i]];
        cards[i].remove();
    }

    cardsArray.forEach(t => document.body.appendChild(t));
}

推荐阅读