我遇到了一个只能在最新的IE 11版本(11.0.9600.1828CO)中重现的问题,并且想知道是否存在我做错的事情,或者这是否是针对浏览器提交的错误。
我想要实现的是通过在HTML元素上使用纯JavaScript交换它们来重新排列各自行中的现有td / th元素。问题似乎是当我将第一行绝对定位以实现固定的标题行时,tr元素的单元格属性未正确更新。
<tr id="headerRow" style="position: absolute; top: 0px;"><th>Column 0</th><th>Column 1</th><th>Column 2</th><th>Column 3</th><th>Column 4</th><th>Column 5</th></tr>
算法很简单:
源元素:交换的最大行索引(例如4)
目标元素:交换的两个最小行索引(例如3)
1)记录具有最大行索引的下一个兄弟元素(称为sourceElement)以供稍后参考(如果它存在)(如果在行的末尾则可能不会)
2)如果目标元素有兄弟,请使用insertBefore将源元素放在它之前,否则将appendChild放在行中,因为目标必须是最后一个单元格
3)然后如果在第一步找到兄弟姐妹,使用insertBefore将目标元素放在它之前,否则appendChild出于同样的原因
4)对表中的每一行重复此操作
这是JS小提琴:
window.clickFunction = function(currentIndex, newIndex) {
window.swapColumns(currentIndex,5);
window.swapColumns(newIndex,5);
window.swapColumns(currentIndex,5);
};
window.swapColumns = function(currentIndex, newIndex) {
// Swap so that the largest index is always inserted before the other
if (currentIndex < newIndex)
{
var tempIndex = newIndex;
newIndex = currentIndex;
currentIndex = tempIndex;
}
$("#beforeCells").html("Before Swap: Should Have 6 Cell Count Each");
$("#afterCells").html("After Swap: Should Have 6 Cell Count Each");
if (newIndex !== -1 && currentIndex !== -1 && currentIndex !== newIndex) {
// Iterate through each row, swapping the elements
var rows = $("#myTable > tbody > tr");
var numRows = rows.length;
var tbody = document.getElementById("myBody");
// Calculate if the index is in the middle of the column groups
var tr, sourceElement, targetElement;
for (var rowIndex = 0; rowIndex < numRows; rowIndex++) {
tr = rows[rowIndex];
sourceElement = tr.cells[currentIndex]; // 3
targetElement = tr.cells[newIndex]; // 5 (because we swapped)
// Only print header and first row (after all are the same as first row)
if (rowIndex === 0 || rowIndex === 1) {
$("#beforeCells").html($("#beforeCells").html() + "<br>" + tr.cells.length);
}
if (typeof sourceElement !== "undefined" && typeof targetElement !== "undefined") {
// Keep a reference to swap in the target element
var sourceSibling = sourceElement.nextSibling;
if (targetElement.nextSibling) {
tr.insertBefore(sourceElement, targetElement);
} else {
tr.appendChild(sourceElement);
}
if (sourceSibling) {
// Place column before target, shift columns left
tr.insertBefore(targetElement, sourceSibling);
} else {
tr.appendChild(targetElement);
}
}
// Only print header and first row (after all are the same as first row)
if (rowIndex === 0 || rowIndex === 1) {
$("#afterCells").html($("#afterCells").html() + "<br>" + tr.cells.length);
}
}
}
};
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style= "position: relative; overflow: hidden; padding-top: 30px;">
<div style="height: 200px; overflow: auto;">
<table id="myTable" style="table-layout: fixed;">
<tbody id="myBody">
<tr id="headerRow" style="position: absolute; top: 0px;"><th>Column 0</th><th>Column 1</th><th>Column 2</th><th>Column 3</th><th>Column 4</th><th>Column 5</th></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
<tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
</tbody>
</table>
</div>
</div>
<button onClick="swapColumns(3, 4)">
Click Me (Cells are broken)!
</button>
<button onClick="clickFunction(3, 4)">
Click Me For Workaround (Refresh First)!
</button>
<div id="beforeCells">
Before Swap: Should Have 6 Cell Count Each
</div>
<div id="afterCells">
After Swap: Should Have 6 Cell Count Each
</div>
&#13;
注意:我没有在我自己的代码中使用JQuery,它只是在小提琴中用来加速访问和嵌入我的示例文本。
我还提供了一个我找到的解决方法,它允许我执行SAME交换而不会使单元格列表不同步。关键是我的每个交换操作都涉及行中的最后一个单元格元素。请参阅示例中的内容。
干杯!