打乱容器的DOM元素,但不是所有的JavaScript

zpf6vheq  于 2023-09-29  发布在  Java
关注(0)|答案(2)|浏览(76)

尝试用特定的类名(“div”)来打乱容器(一个div)的DOM元素(其他div)。其他的divs(“额外的”)应该呆在他们所在的地方。
到目前为止,我使用的是来自link的修改后的shuffle算法
我的代码几乎做到了这一点,但“额外”div被附加在堆栈的底部,而它应该留在顶部。

let divs       = document.getElementsByClassName("div")
let divsNumber = divs.length;
let divver     = document.getElementsByClassName("divver")[0]

function shuffler() {
  for (var i = divsNumber; i >= 0; i--) {
    if (!divver.children[i].classList.contains("div")) {
      divver.appendChild(divver.children[Math.random() * i | 0]);
    }
  }
}
<div class="divver">
  <div class="extra">  Extra  </div>
  <div class="div">    1  </div>
  <div class="div">    2  </div>
  <div class="div">    3  </div>
  <div class="div">    4  </div>
  <div class="div">    5  </div>
</div>

<button onclick="shuffler()" id="shuffles">Shuffle 'em</button>

任何提示都非常感谢。

643ylb08

643ylb081#

const
  divver      = document.querySelector('div.divver')
, ShuffleDivs = [...divver.querySelectorAll('div:not(.extra)')]
  ;
document.querySelector('button#shuffles').onclick = () =>
  {
  let r_Idx; // random Index;

  // current index from  ShuffleDivs.length -1 to zero
  for ( let c_Idx = ShuffleDivs.length; c_Idx--; )  
    {
    // Pick one.. in the range[ 0 ... c_Idx]
    r_Idx = Math.floor(Math.random() * c_Idx);      

    // swap Array positions
    [ShuffleDivs[c_Idx], ShuffleDivs[r_Idx]] =
    [ShuffleDivs[r_Idx], ShuffleDivs[c_Idx]]; 
    }

  // replace them in the new Shuffle order...
  for (let i = 0; i < ShuffleDivs.length; i++)
    divver.appendChild(ShuffleDivs[i]);
  }
<div class="divver">
  <div class="extra"> Extra </div>
  <div> 1 </div>
  <div> 2 </div>
  <div> 3 </div>
  <div> 4 </div>
  <div> 5 </div>
</div>

<button id="shuffles">Shuffle 'em</button>

为了避免移动指向DOM元素的指针,
我只是在这里使用他们在接口上的位置索引(aOrder):

const
  divver      = document.querySelector('div.divver')
, ShuffleDivs = divver.querySelectorAll('div:not(.extra)')
, aOrder      = Array.from(ShuffleDivs,(_,i)=>i)  // array of elements position order
  ;
document.querySelector('button#shuffles').onclick = () =>
  {
  let r; // random Index;

  for ( let c = aOrder.length; c--; ) //  current Index; 
    {
    r = 0|(Math.random() * c);        // Pick one range[ 0 ... c]
    [aOrder[c], aOrder[r]] = [aOrder[r], aOrder[c]]; // swap positions
    }
  for (let pos of aOrder)   
    divver.appendChild(ShuffleDivs[pos]);
  }
<div class="divver">
  <div class="extra">  Extra  </div>
  <div> 1 </div>
  <div> 2 </div>
  <div> 3 </div>
  <div> 4 </div>
  <div> 5 </div>
</div>

<button id="shuffles">Shuffle 'em</button>

我郑重声明
评论来自ViliusL
“1”总是在底部。
完全正确!前面的算法总是把第一个元素放在最后。实际上,初始集合总是以相同的顺序读取。
我通过将div的集合更改为Array来修复它,这样我就可以实际更改它们的顺序。所以任何新的 Shuffle 都将基于他们的实际位置。

  • 第一个“不正确”的答案:*
const
  divver      = document.querySelector('div.divver')
, ShuffleDivs = divver.querySelectorAll('div.div') // just select this group
  ;
document.querySelector('button#shuffles').onclick = () =>
  {
  for (let i = ShuffleDivs.length; i >= 0; i--)
    divver.appendChild(ShuffleDivs[Math.random() * i | 0]);
  }
7lrncoxx

7lrncoxx2#

由于您希望将第一个元素排除在shuffle之外,并且元素数组以0为基础,因此可以将* i | 0]更改为* i | 1]

let divs       = document.getElementsByClassName("div")
let divsNumber = divs.length;
let divver     = document.getElementsByClassName("divver")[0]

function shuffler() {
  for (var i = divsNumber; i >= 0; i--) {
    if (!divver.children[i].classList.contains("div")) {
      divver.appendChild(divver.children[Math.random() * i | 1]);
    }
  }
}
<div class="divver">
  <div class="extra">  Extra  </div>
  <div class="div">    1  </div>
  <div class="div">    2  </div>
  <div class="div">    3  </div>
  <div class="div">    4  </div>
  <div class="div">    5  </div>
</div>

<button onclick="shuffler()" id="shuffles">Shuffle 'em</button>

相关问题