我正在尝试转置包含具有rowspancellspan属性的单元格的表。我已经尝试过对表进行转置的示例(herehere),但是它们没有考虑单元格的大小-因此,行和列最终会变得太长或太短。

如何摆放桌子并确保它保持矩形。



这是我的html表。



table tr:first-child {
  color: #FFFFFF;
  background-color: #639187;
}

table tr td:first-child {
  color: #FFFFFF;
  background-color: #639187;
}

<table cellspacing="0" border="1">
  <tbody>
    <tr>
      <td></td>
      <td colspan="1">9:00</td>
      <td colspan="1">9:15</td>
      <td colspan="1">9:30</td>
      <td colspan="1">9:45</td>
      <td colspan="1">10:00</td>
      <td colspan="1">10:15</td>
      <td colspan="1">10:30</td>
      <td colspan="1">10:45</td>
      <td colspan="1">11:00</td>
      <td colspan="1">11:15</td>
      <td colspan="1">11:30</td>
      <td colspan="1">11:45</td>
      <td colspan="1">12:00</td>
      <td colspan="1">12:15</td>
      <td colspan="1">12:30</td>
      <td colspan="1">12:45</td>
      <td colspan="1">13:00</td>
      <td colspan="1">13:15</td>
      <td colspan="1">13:30</td>
      <td colspan="1">13:45</td>
      <td colspan="1">14:00</td>
      <td colspan="1">14:15</td>
      <td colspan="1">14:30</td>
      <td colspan="1">14:45</td>
      <td colspan="1">15:00</td>
      <td colspan="1">15:15</td>
      <td colspan="1">15:30</td>
      <td colspan="1">15:45</td>
      <td colspan="1">16:00</td>
      <td colspan="1">16:15</td>
      <td colspan="1">16:30</td>
      <td colspan="1">16:45</td>
      <td colspan="1">17:00</td>
      <td colspan="1">17:15</td>
      <td colspan="1">17:30</td>
      <td colspan="1">17:45</td>
      <td colspan="1">18:00</td>
    </tr>

    <tr>
      <td rowspan="1">Madrid</td>
      <td style="background-color: rgb(204, 204, 204);" colspan="4" rowspan="1"></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td style="background-color: rgb(204, 204, 204);" colspan="4" rowspan="1"></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td rowspan="1">London</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td style="background-color: rgb(204, 204, 204);" colspan="4" rowspan="1"></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td style="background-color: rgb(204, 204, 204);" colspan="4" rowspan="1"></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td style="background-color: rgb(204, 204, 204);" colspan="4" rowspan="1"></td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td rowspan="1">Paris</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td colspan="12" rowspan="1" style="background-color: rgb(204, 204, 204);"></td>
      <td colspan="4" rowspan="1" style="background-color: rgb(204, 204, 204);"></td>
      <td>&nbsp;</td>
    </tr>
  </tbody>
</table>

最佳答案

我发现使用普通的旧JavaScript要做这是一个不错的挑战。它与a previous question that I don't think it's a duplicate足够不同。请注意,以下代码仅适用于原始表中的rowspan。但是,该逻辑应适用于colspan

它还不考虑页眉(theadth s)或页脚(tfooter s)。我认为解决这些问题并不困难。

我已经在下面的代码中添加了注释,以寻求指导,但是请务必提出任何问题。



console.time();
const transpose = m => m[0].map((x, i) => m.map(x => x[i]));
const table = document.getElementById("transposed");
const rows = Array.from(table.querySelectorAll("tr"));
const totalRowCount = rows.length;

// First, create an array of the rows and within each element,
// an array of the cells; easier to deal with than NodeLists.

// This could be done more cleverly with map or reduce, but
// I like good old fashioned for loops.

const m = new Array(totalRowCount);
for (let r = 0; r < rows.length; r++) {
  const row = rows[r];
  const cells = Array.from(row.querySelectorAll("td"));
  m[r] = [];
  for (let c = 0; c < cells.length; c++) {
    const cell = cells[c];
    let rowspan = cell.getAttribute("rowspan");
    let colspan = cell.getAttribute("colspan");
    rowspan = rowspan && parseInt(rowspan, 10);
    colspan = colspan && parseInt(colspan, 10);

    // Note that I'm swapping colspan and rowspan here in the
    // cells of my array. I could do this after transposition,
    // but felt like doing it here.

    // Note also that unlike in the duplicate question, I
    // default the attribute to 1 rather than 0. I found that
    // some browsers get messed up with spanning 0 rows/columns.

    cell.setAttribute("colspan", rowspan || 1);
    cell.setAttribute("rowspan", colspan || 1);

    // I'm using a temporary object here to make it easier to
    // access information about the cell later on, without adding
    // that information to the DOM.

    m[r].push({
      element: cell,
      index: c,
      rowspan: rowspan || 0,
      colspan: colspan || 0
    });
  }
}

// Now m contains an array of arrays. Each of the 4 elements
// in the topmost array contains a different number of elements.
// The elements are objects containing the <td>, its index in
// the row and the rowspan and colspan for that cell.

// So, we'll build another array of arrays, this time with
// objects to represent the cells that are spanned.

let rowsToSpan = 0;
let colsToSpan = 0;
let cellsToInject = new Array(m.length);
for (let r = 0; r < m.length; r++) {
  let colSpannedCells = m[r].filter(c => c.colspan && c.colspan > 1);
  cellsToInject[r] = new Array(colSpannedCells.length);
  for (let c = 0; c < colSpannedCells.length; c++) {
    let cell = colSpannedCells[c];
    cellsToInject[r].push({
      index: cell.index,
      cells: new Array(cell.colspan - 1)
    });
  }
}

// Now we have an array of arrays of the cells we want to inject, so we iterate
// over them, splicing the "empty" cells into the array.
var r = 0;

// One might wonder why I'm using for..of here, where I didn't previously; good
// question. :) I was playing around with performance (hence the console.time() and
// console.timeEnd()) and wanted to see the effect. This would work just as well
// with a normal for loop.

for (let row of cellsToInject) {
  if (row && row.length) {
    var injectIndex = 0;
    var injectCount = 0;
    for (let col of row) {
      if (col && col.cells.length) {
        col.cells.fill({
          element: null,
          rowspan: null,
          colspan: null
        });

        // The trick here is to ensure we're taking account of previously
        // injected cells to ensure the new set of cells are injected in
        // the correct place.

        injectIndex = col.index + injectCount + 1;
        Array.prototype.splice.apply(m[r], [injectIndex, 0, ...col.cells])

        // Keeping a running tally of the number of cells injected helps.
        injectCount += col.cells.length;
      }
    }
  }
  r++;
}

// Now m is an array of arrays, with each element in the topmost
// array having an equal number of elements. This makes the transposition
// work better.

const transposed = transpose(m);

// Now we remove the tbody and inject our own.

table.removeChild(table.querySelector("tbody"));
let tbody = document.createElement("tbody");

// Just iterate over the transposed array, creating a row for each
// element, and iterate over the nested array, adding the element
// for each (where present) back in.

for (let rw of transposed) {
  const row = document.createElement("tr");
  for (let ce of rw) {
    if (ce && ce.element) {
      row.appendChild(ce.element);
    }
  }
  tbody.appendChild(row);
}
table.appendChild(tbody);
console.timeEnd();

table tr:first-child {
  color: #FFFFFF;
  background-color: #639187;
}

table tr td:first-child {
  color: #FFFFFF;
  background-color: #639187;
}

<table cellspacing="0" border="1" id="not-transposed">
  <tbody>
    <tr>
      <td></td>
      <td colspan="1">9:00</td>
      <td colspan="1">9:15</td>
      <td colspan="1">9:30</td>
      <td colspan="1">9:45</td>
      <td colspan="1">10:00</td>
      <td colspan="1">10:15</td>
      <td colspan="1">10:30</td>
      <td colspan="1">10:45</td>
      <td colspan="1">11:00</td>
      <td colspan="1">11:15</td>
      <td colspan="1">11:30</td>
      <td colspan="1">11:45</td>
      <td colspan="1">12:00</td>
      <td colspan="1">12:15</td>
      <td colspan="1">12:30</td>
      <td colspan="1">12:45</td>
      <td colspan="1">13:00</td>
      <td colspan="1">13:15</td>
      <td colspan="1">13:30</td>
      <td colspan="1">13:45</td>
      <td colspan="1">14:00</td>
      <td colspan="1">14:15</td>
      <td colspan="1">14:30</td>
      <td colspan="1">14:45</td>
      <td colspan="1">15:00</td>
      <td colspan="1">15:15</td>
      <td colspan="1">15:30</td>
      <td colspan="1">15:45</td>
      <td colspan="1">16:00</td>
      <td colspan="1">16:15</td>
      <td colspan="1">16:30</td>
      <td colspan="1">16:45</td>
      <td colspan="1">17:00</td>
      <td colspan="1">17:15</td>
      <td colspan="1">17:30</td>
      <td colspan="1">17:45</td>
      <td colspan="1">18:00</td>
    </tr>

    <tr>
      <td rowspan="1">Madrid</td>
      <td style="background-color: rgb(204, 204, 204);" colspan="4" rowspan="1"></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td style="background-color: rgb(204, 204, 204);" colspan="4" rowspan="1"></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td rowspan="1">London</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td style="background-color: rgb(204, 204, 204);" colspan="4" rowspan="1"></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td style="background-color: rgb(204, 204, 204);" colspan="4" rowspan="1"></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td style="background-color: rgb(204, 204, 204);" colspan="4" rowspan="1"></td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td rowspan="1">Paris</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td colspan="12" rowspan="1" style="background-color: rgb(204, 204, 204);"></td>
      <td colspan="4" rowspan="1" style="background-color: rgb(204, 204, 204);"></td>
      <td>&nbsp;</td>
    </tr>
  </tbody>
</table>
<table cellspacing="0" border="1" id="transposed">
  <tbody>
    <tr>
      <td></td>
      <td colspan="1">9:00</td>
      <td colspan="1">9:15</td>
      <td colspan="1">9:30</td>
      <td colspan="1">9:45</td>
      <td colspan="1">10:00</td>
      <td colspan="1">10:15</td>
      <td colspan="1">10:30</td>
      <td colspan="1">10:45</td>
      <td colspan="1">11:00</td>
      <td colspan="1">11:15</td>
      <td colspan="1">11:30</td>
      <td colspan="1">11:45</td>
      <td colspan="1">12:00</td>
      <td colspan="1">12:15</td>
      <td colspan="1">12:30</td>
      <td colspan="1">12:45</td>
      <td colspan="1">13:00</td>
      <td colspan="1">13:15</td>
      <td colspan="1">13:30</td>
      <td colspan="1">13:45</td>
      <td colspan="1">14:00</td>
      <td colspan="1">14:15</td>
      <td colspan="1">14:30</td>
      <td colspan="1">14:45</td>
      <td colspan="1">15:00</td>
      <td colspan="1">15:15</td>
      <td colspan="1">15:30</td>
      <td colspan="1">15:45</td>
      <td colspan="1">16:00</td>
      <td colspan="1">16:15</td>
      <td colspan="1">16:30</td>
      <td colspan="1">16:45</td>
      <td colspan="1">17:00</td>
      <td colspan="1">17:15</td>
      <td colspan="1">17:30</td>
      <td colspan="1">17:45</td>
      <td colspan="1">18:00</td>
    </tr>

    <tr>
      <td rowspan="1">Madrid</td>
      <td style="background-color: rgb(204, 204, 204);" colspan="4" rowspan="1"></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td style="background-color: rgb(204, 204, 204);" colspan="4" rowspan="1"></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td rowspan="1">London</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td style="background-color: rgb(204, 204, 204);" colspan="4" rowspan="1"></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td style="background-color: rgb(204, 204, 204);" colspan="4" rowspan="1"></td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td style="background-color: rgb(204, 204, 204);" colspan="4" rowspan="1"></td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td rowspan="1">Paris</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td colspan="12" rowspan="1" style="background-color: rgb(204, 204, 204);"></td>
      <td colspan="4" rowspan="1" style="background-color: rgb(204, 204, 204);"></td>
      <td>&nbsp;</td>
    </tr>
  </tbody>
</table>





注意:transpose通过this answerTransposing a 2D-array in JavaScriptMahdi Jadaliha

关于javascript - 具有'colspan'和'rowspan'属性的转置表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52189230/

10-09 15:03