为什么这个随机播放功能仅适用于4个以上的项目? JsFiddle包括

时间:2018-06-08 18:41:49

标签: javascript jquery shuffle

我有以下代码,它会在表格的行中混洗一组项目。但是,shuffle功能仅在有4个以上的项目时才有效:

var parent = $("#parent");


function shuffleRows(parent) {
  var rows = parent.children().children(".shuffledtd1");
  for (var i = rows.length - 1; i > 0; i--) {
    var j = Math.floor(Math.random() * (i + 1));
    var temp = rows[i];
    rows.eq(i - 1).after(rows[j]);
    rows.eq(j - 1).after(temp);
  }
}

shuffleRows(parent);
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<table>
  <tbody id="parent">

    <tr id="node2" class="shufflerow">
      <td class="shuffledtd shuffledtd1">AA</td>
      <td class="shuffledtd shuffledtd1">BB</td>

      <!-- IF I DELETE THIS AND THE FOLLOWING ROW, THE PRIOR 2 ROWS NO LONGER SHUFFLE -->
      <td class="shuffledtd shuffledtd1">CC</td>
      <td class="shuffledtd shuffledtd1">DD</td>
    </tr>

  </tbody>
</table>

完整代码:http://jsfiddle.net/d8rkgx0z/

我认为它与代码的这一部分有关:

    rows.eq(i - 1).after(rows[j]);
    rows.eq(j - 1).after(temp);

但是,不幸的是,我的技能设置不够强大,无法在没有数小时的反复试验的情况下隔离和纠正问题。

提前感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

不要再调用children两次,只需传入单元格的直接父级。此外,使用jQuery#sort

可以更轻松地改变孩子
var parent = $("#node2");                                        // parent should be the tr element not the tbody which is in fact a grandparent not a parent

function shuffleChildren(parent) {
  parent.children()                                              // get the children of the parent element
        .sort(function() { return Math.random() - 0.5; })        // sort them randomly (shuffling)
        .appendTo(parent);                                       // add them back to parent so that the shuffling takes effect
}

shuffleChildren(parent);

示例:

var parent = $("#node2");                                        // parent should be the tr element not the tbody which is in fact a grandparent not a parent

function shuffleChildren(parent) {
  parent.children()                                              // get the children of the parent element
        .sort(function() { return Math.random() - 0.5; })        // sort them randomly (shuffling)
        .appendTo(parent);                                       // add them back to parent so that the shuffling takes effect
}

shuffleChildren(parent);
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<table>
  <tbody id="parent">
    <tr id="node2" class="shufflerow">
      <td class="shuffledtd shuffledtd1">AA</td>
      <td class="shuffledtd shuffledtd1">BB</td>
      <td class="shuffledtd shuffledtd1">CC</td>
      <td class="shuffledtd shuffledtd1">DD</td>
    </tr>
  </tbody>
</table>

注意:如果要对所有行执行此操作,请使用jQuery#each

$("#parent tr").each(function() {                                // get all tr inside #parent
    shuffleChildren($(this));                                    // shuffle their children
});
顺便说一下,你洗牌的是细胞而不是行。

答案 1 :(得分:1)

ibrahim mahrir的答案是更优雅的方式来做你想做的事情,但为了帮助你理解为什么你的解决方案没有工作我发布了这也是。

问题:

你看到的问题是因为当i = 0时,当你做(i - 1)时你会得到负数,这不是你表中的有效索引。

  

rows.eq(i - 1).after(rows [j]);

使您的解决方案有效的方法:

以下是您使用现有代码解决该问题的方法:

&#13;
&#13;
function shuffleRows(parent) {
    var rows = parent.children().children(".shuffledtd1");
    // Changed to i >= 0.
    for (var i = rows.length - 1; i >= 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var temp = rows[i];
        // Changed to just i, instead if i-1.
        rows.eq(i).after(rows[j]);
        rows.eq(j - 1).after(temp);
    }
}

$('button').on('click', function() {
	shuffleRows($("#parent"));
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<table>
    <tbody id="parent">

        <tr id="node2" class="shufflerow">
            <td class="shuffledtd shuffledtd1">AA</td>
            <td class="shuffledtd shuffledtd1">BB</td>
            <td class="shuffledtd shuffledtd1">CC</td>

        </tr>
  
    </tbody>
</table>
<button>Shuffle</button>
&#13;
&#13;
&#13;

这段代码只做了两处小改动,我在代码中注意到,以避免你的负面索引问题。

同样,有更多优雅的方法来完成这项任务,但我总是理解为什么有些东西不起作用,所以我希望你有一个解释。

答案 2 :(得分:0)

您的脚本可以非常简化,特别是使用正确的选择器和随机分类器(涵盖tdtrtrtbody的排序const randomSorter = () => 0.5 - Math.random(); $('.shufflecells tr').each(function() { $(this).html($('td', this).sort(randomSorter)); }); $('.shufflerows').each(function() { $(this).html($('tr', this).sort(randomSorter)); }); }}:

&#13;
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<table>
  <tbody class="shufflecells">
    <tr>
      <td>AA</td>
      <td>BB</td>
      <td>CC</td>
      <td>DD</td>
    </tr>
  </tbody>
</table>

<table>
  <tbody class="shufflecells">
    <tr>
      <td>AA</td>
      <td>BB</td>
    </tr>
  </tbody>
</table>

<table>
  <tbody class="shufflerows">
    <tr>
      <td>AA</td>
    </tr>
    <tr>
      <td>BB</td>
    </tr>
    <tr>
      <td>CC</td>
    </tr>
    <tr>
      <td>DD</td>
    </tr>
  </tbody>
</table>
&#13;
div.controls
&#13;
&#13;
&#13;