这是非常独特的要求,我想实现向上/向下(排序顺序行)功能。我可以使用 jQuery 进行向上/向下操作,但我需要复杂的要求,我尝试过但无法做到。正如我附上的快照。如果我点击向下按钮 #trMain-1989 那么接下来 4 行的那一行会在 #trMain-1991
之后移动如果我单击 #trMain-1995 的向上按钮,那么它会将所有 5 行(#trMain-1995、#trLang-1995、#trQuestion-1995、#trAnswer-1995 和 #trAct-1995)移动到之前#trMain-1993
这是我最近 3-4 天尝试过的代码,但没有成功。
代码:1
$(document).on('click','.fas', function(event){
var $element = this;
var row = $($element).parents("tr:first");
let index = oTable.row(row).index();
console.log(index);
if($(this).is('.up')){
row.eq(index-4).insertBefore(row.prev());
}else{
row.eq(index+4).insertAfter(row.next());
}
return false;
});
代码:2
$(document).on('click','.fas', function(event){
if(oTable){
let tr = $(this).closest('tr');
let cls = $(tr).attr("class");
//console.log(cls);
cls = cls.split("-");
//console.log(cls[1]);
let index = oTable.row(tr).index();
let indexes = oTable.rows()[0];
let order = -1;
let buttonName = event.currentTarget.className;
if(buttonName.indexOf('down') > 0){
order = 1;
}
let data1 = oTable.row(index).data();
console.log(data1);
let base_index = indexes.indexOf(index) + order;
console.log(base_index);
let index2 = indexes[base_index];
console.log(index2);
var data2 = oTable.row(index2).data();
//console.log(data1);
oTable.row(index).data(data2);
oTable.row(index2).data(data1);
});
我希望如果有人可以帮助我纠正我的代码或提供任何明智的解决方案,那么这对我来说会很棒。谢谢
您想像组一样移动它们。
每个组都以
tr
开始,该组的类以 trMain-
开头,并以 tr
结束,该类的类以 trAct-
开头。
为了从
tr_current
向上移动,我们找到前一个 trMain-
并将其称为 tr_target
。我们开始将 tr_current
及其所有下一个兄弟移动到 tr_target
之前,直到 tr_current
指向下一个我们不会移动的 trMain-
。
为了向下移动,逻辑相同,只是稍微高级一点,因为我们向下移动 10 个元素,而不是向上移动 5 个元素。看代码。
document.querySelectorAll(".up").forEach(function(button) {
button.addEventListener('click', moveUp)
})
document.querySelectorAll(".down").forEach(function(button) {
button.addEventListener('click', moveDown)
})
function moveUp(ev) {
var tr_current = ev.target.closest('tr')
// find previous tr that has class that starts with 'main-'
var tr_target = tr_current.previousElementSibling
while (tr_target && ![...tr_target.classList].some((cls) => cls.startsWith('trMain-'))) {
tr_target = tr_target.previousElementSibling
}
if (!tr_target) {
return
}
// move each tr_current before tr_target until has class that starts with 'main-'
do {
var next = tr_current.nextElementSibling
tr_current.parentNode.insertBefore(tr_current, tr_target)
tr_current = next
} while (tr_current && ![...tr_current.classList].some((cls) => cls.startsWith('trMain-')))
}
// same logic but a step further
function moveDown(ev) {
var tr_current = ev.target.closest('tr')
var tr_target = tr_current.nextElementSibling
while (tr_target && ![...tr_target.classList].some((cls) => cls.startsWith('trMain-'))) {
tr_target = tr_target.nextElementSibling
}
if (!tr_target) {
return
}
var tr_target = tr_target.nextElementSibling
while (tr_target && ![...tr_target.classList].some((cls) => cls.startsWith('trAct-'))) {
tr_target = tr_target.nextElementSibling
}
do {
var next = tr_current.nextElementSibling
tr_current.parentNode.insertBefore(tr_current, tr_target.nextElementSibling)
tr_current = next
tr_target = tr_target.nextElementSibling
} while (tr_current && ![...tr_current.classList].some((cls) => cls.startsWith('trMain-')))
}
table {
width: 100%;
border-collapse: collapse;
}
[class*="trMain-"] {
background: yellow;
}
<table border="1">
<tbody>
<tr class="trMain-1989">
<td>trMain 1989 <button class="up">up</button> <button class="down">down</button></td>
</tr>
<tr class="trLang-1989">
<td>trLang 1989</td>
</tr>
<tr class="trQuestion-1989">
<td>trQuestion 1989</td>
</tr>
<tr class="trAnswer-1989">
<td>trAnswer 1989</td>
</tr>
<tr class="trAct-1989">
<td>trAct 1989</td>
</tr>
<tr class="trMain-1991">
<td>trMain 1991 <button class="up">up</button> <button class="down">down</button></td>
</tr>
<tr class="trLang-1991">
<td>trLang 1991</td>
</tr>
<tr class="trQuestion-1991">
<td>trQuestion 1991</td>
</tr>
<tr class="trAnswer-1991">
<td>trAnswer 1991</td>
</tr>
<tr class="trAct-1991">
<td>trAct 1991</td>
</tr>
<tr class="trMain-1993">
<td>trMain 1993 <button class="up">up</button> <button class="down">down</button></td>
</tr>
<tr class="trLang-1993">
<td>trLang 1993</td>
</tr>
<tr class="trQuestion-1993">
<td>trQuestion 1993</td>
</tr>
<tr class="trAnswer-1993">
<td>trAnswer 1993</td>
</tr>
<tr class="trAct-1993">
<td>trAct 1993</td>
</tr>
<tr class="trMain-1995">
<td>trMain 1995 <button class="up">up</button> <button class="down">down</button></td>
</tr>
<tr class="trLang-1995">
<td>trLang 1995</td>
</tr>
<tr class="trQuestion-1995">
<td>trQuestion 1995</td>
</tr>
<tr class="trAnswer-1995">
<td>trAnswer 1995</td>
</tr>
<tr class="trAct-1995">
<td>trAct 1995</td>
</tr>
</tbody>
</table>
由于您当前的架构已经有了答案,我将建议一些改进。
当元素名称也是
tr
时,用 tr
预先固定类名是多余的。这会扩展到 tr.trMain-1999
,也可以缩减为 tr.main-1999
,而不会丢失任何信息。
您的类名称似乎后固定了年份,并且由于我们要按此数据进行分组,因此您可以将其存储为
data-
属性而不是类。
let GetGroup = (group) => $(`table tr[data-group="${group}"]`);
$('table') //this is just boiler plate to generate a table
.html([...Array(10)].map((u, i) => ['main','language','question','answer','act'].map((item) => `<tr class="${item}" data-group="${i + 1985}" style="background-color:#${(i * 369e3).toString(16).padStart(6, '0')}22"><td><button data-move="up">↑</button><button data-move="down">↓</button><span>${i + 1985}</span><span>${item}</span></td></tr>`)).join(''))
.on('click', 'button[data-move]', function() {
let $group = GetGroup($(this).parents('tr').attr('data-group'));
({
up: () => {
if ($group.first().prev()) { //can we move up?
$group.insertBefore(
GetGroup($group.first().prev().attr('data-group')).first());
}
},
down: () => {
if ($group.last().next()) { //can we move down?
$group.insertAfter(
GetGroup($group.last().next().attr('data-group')).last());
}
}
}[this.dataset.move])(); //which button was clicked
});
<table></table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>