为什么这个随机播放功能只适用于 4+ 项目?包含 JsFiddle
Why does this shuffle function only work with 4+ items? JsFiddle included
我有以下代码,它随机播放 table 行中的一组项目。但是,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);
但是,不幸的是,我的技能不够强大,无法在没有数小时的反复试验的情况下隔离和纠正问题。
在此先感谢您的帮助!
不用调用children
两次,直接传入单元格的parent即可。此外,使用 jQuery#sort
:
洗牌 children 更容易
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
});
顺便说一句,您要洗牌的是单元格而不是行。
您的脚本可以大大简化,尤其是使用适当的选择器和随机排序器(涵盖了在 tr
中排序 td
或 tr
中的两种情况 tbody
:
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));
});
<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>
ibrahim mahrir 的回答是做你想做的事情的更优雅的方式,但为了帮助你理解为什么你的解决方案不起作用,我也发布了这个。
问题:
您看到的问题是因为当 i = 0 时,当您执行 (i - 1) 时得到负数,这在您的 table.
中不是有效索引
rows.eq(i - 1).after(rows[j]);
使您的解决方案有效的方法:
以下是您可以如何使用现有代码解决该问题:
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"));
});
<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>
这个代码片段只是做了两个小改动,我在代码中做了标记,以避免您遇到的负索引问题。
同样,有很多更优雅的方法来完成这项任务,但我总是搞不懂为什么有些东西不起作用,所以我希望你能得到一个解释。
我有以下代码,它随机播放 table 行中的一组项目。但是,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);
但是,不幸的是,我的技能不够强大,无法在没有数小时的反复试验的情况下隔离和纠正问题。
在此先感谢您的帮助!
不用调用children
两次,直接传入单元格的parent即可。此外,使用 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
});
顺便说一句,您要洗牌的是单元格而不是行。
您的脚本可以大大简化,尤其是使用适当的选择器和随机排序器(涵盖了在 tr
中排序 td
或 tr
中的两种情况 tbody
:
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));
});
<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>
ibrahim mahrir 的回答是做你想做的事情的更优雅的方式,但为了帮助你理解为什么你的解决方案不起作用,我也发布了这个。
问题:
您看到的问题是因为当 i = 0 时,当您执行 (i - 1) 时得到负数,这在您的 table.
中不是有效索引rows.eq(i - 1).after(rows[j]);
使您的解决方案有效的方法:
以下是您可以如何使用现有代码解决该问题:
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"));
});
<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>
这个代码片段只是做了两个小改动,我在代码中做了标记,以避免您遇到的负索引问题。
同样,有很多更优雅的方法来完成这项任务,但我总是搞不懂为什么有些东西不起作用,所以我希望你能得到一个解释。