具有'colspan'和'rowspan'属性的转置表 [英] Transpose Table with 'colspan' and 'rowspan' Attribute

查看:78
本文介绍了具有'colspan'和'rowspan'属性的转置表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to transpose a table that has cells with the rowspan and cellspan attributes. I've tried examples (here and here) that transpose tables, but they don't account for the cell size - therefore the rows and columns end up being too long or too short.

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

How can I transpose my table and ensure it remains rectangular.

这是我的表格的html.

This is my html for the table.

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很难做到这一点.它与上一个问题(我认为不是重复的问题)有足够的区别.请注意,下面的代码仅适用于原始表中的rowspan.但是,该逻辑应适用于colspan.

I found this a nice challenge to do using plain old JavaScript. It differs enough from a previous question that I don't think it's a duplicate. Note that the code below works only for rowspans in the original table; the logic should be adaptable for colspans however.

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

It also doesn't take into account headers (theads or ths) or footers (tfooters). I don't think it would be horribly difficult to account for them.

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

I've added comments to the code below for guidance, but please do ask any questions you might have.

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来自此答案 Mahdi Jadaliha 用JavaScript转置2D数组.

Note: transpose comes from this answer to Transposing a 2D-array in JavaScript by Mahdi Jadaliha.

这篇关于具有'colspan'和'rowspan'属性的转置表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆