使用JavaScript合并表行

使用JavaScript合并表行,javascript,html,css,Javascript,Html,Css,我使用的是普通表,以下是我的要求: 如果表行值重复,则应使用javascript将其合并。例如:表1行值和表2行值相同,则应将其合并,并使用javascript仅显示一次值。这里我将附上我的代码 函数myFunction(){ 常量firstRows={}; 让阴影=虚假; const colsToMerge=[0,1]; from(document.querySelectorAll('tbody tr')).forEach(tr=>{ const text=tr.children[0]。in

我使用的是普通表,以下是我的要求:

如果表行值重复,则应使用javascript将其合并。例如:表1行值和表2行值相同,则应将其合并,并使用javascript仅显示一次值。这里我将附上我的代码

函数myFunction(){
常量firstRows={};
让阴影=虚假;
const colsToMerge=[0,1];
from(document.querySelectorAll('tbody tr')).forEach(tr=>{
const text=tr.children[0]。innerText;
如果(!(第一行中的文本)){
第一行[文本]={shade,elem:tr,count:1};
阴影=!阴影;
}否则{
const firstRow=第一行[文本]
firstRow.count++;
forEach(i=>tr.children[i].remove());
colsToMerge.forEach(i=>
第一排。元素。儿童[i]
.setAttribute('rowspan',firstRow.count)
);
}
if(firstRows[text].shade)tr.classList.add('dark');
});
}
表格{
字体系列:arial,无衬线;
边界塌陷:塌陷;
宽度:100%;
}
th{
背景:#A9A9;
}
运输署,
th{
边框:1px实心#dddddd;
文本对齐:居中;
填充:8px;
字体系列:monospace;
字号:17px;
}
.黑暗{
背景色:#dddddd;
}

单位
接触
国家
阿尔弗雷德·福特基斯特
玛丽亚·安德斯
德国因戈
阿尔弗雷德·福特基斯特
玛丽亚·安德斯
德国
莫特祖马商业中心
张锦松
墨西哥
恩斯特·汉德尔
罗兰·孟德尔
奥地利
岛屿贸易
海伦·贝内特
英国
笑巴克斯酒窖
田纳西
加拿大
马加兹尼营养不良
乔瓦尼·罗维利
意大利

您可以通过Javascript动态执行此操作。检查这把小提琴:

let previousObj = [];
const rows = $("table tr");
rows.each(function(i, el) {
    let obj = [];
    $(el).children("td").each(function(ic, elc) {
    obj.push(elc);

    if (previousObj.length > ic) {
        if (previousObj[ic].innerHTML == obj[ic].innerHTML) {
        $(previousObj[ic]).attr('rowspan', getRowsSpan(ic, i, obj[ic].innerHTML));
        $(obj[ic]).remove();
      }      
    }
  });

  previousObj = obj;
});

function getRowsSpan(col, row, value) {
    var rowSpan = 2;
  var actualRow = row+1;

  while ($(rows[actualRow]).children("td")[col].innerHTML == value) {
    rowSpan++;
    actualRow++;
  } 

  return rowSpan;
}

这里有一个工作解决方案,用于动态合并每列中的连续行单元格

该解决方案还可用于切换阴影,仅在“满”行开始时(即连续行之间没有合并时)切换阴影

此外,您必须将
tr
包装在
thead
的表头中,因为这可能会导致
文档出现问题。querySelectorAll('tbody tr')
事件
tbody
在查询中指定

我稍微修改了表格以显示着色和合并:

函数myFunction(){
const previousRow={};
const colsChanged={};
让黑暗=虚假;
Array.from(document.querySelectorAll('tbody tr')).forEach((tr,rowIdx)=>{
数组.from(tr.children).forEach((td,colIdx)=>{
if(rowIdx>0&&previousRow[colIdx].text==td.innerText){
上一行[colIdx].elem.setAttribute('rowspan',++上一行[colIdx].span);
colsChanged[colIdx]=假;
td.删除();
}否则{
上一行[colIdx]={span:1,text:td.innerText,elem:td,dark};
colsChanged[colIdx]=真;
}
});
const rowChanged=Object.values(colsChanged).every(布尔);
dark=rowChanged&&rowIdx>0?!dark:dark;
如果(暗){
tr.classList.add('dark');
}
});
}
表格{
字体系列:arial,无衬线;
边界塌陷:塌陷;
宽度:100%;
}
th{
背景:#A9A9;
}
运输署,
th{
边框:1px纯黑;
文本对齐:居中;
填充:8px;
字体系列:monospace;
字号:17px;
}
.黑暗{
背景色:#dddddd;
}

单位
接触
国家
阿尔弗雷德·福特基斯特
玛丽亚·安德斯
德国因戈
阿尔弗雷德·福特基斯特
玛丽亚·安德斯
德国
莫特祖马商业中心
张锦松
墨西哥
恩斯特·汉德尔
张锦松
奥地利
恩斯特·汉德尔
海伦·贝内特
英国
笑巴克斯酒窖
田纳西
加拿大
Magazzini Alimentari Riuniti 1
乔瓦尼·罗维利1号
意大利
Magazzini Alimentari Riuniti 2
乔瓦尼·罗维利2号
意大利
Magazzini Alimentari Riuniti 3
乔瓦尼·罗维利3
意大利

在下面的代码片段中,我首先将表中的数据读取到js数组中,然后将具有类似第一列的行合并,并生成表体的新html内容

let readTable=(tbody)=>[…tbody.rows].map(row=>[…row.cells].map(c=>c.innerText));
函数合并行(数据){
设h={};
data.forEach((r,i)=>{//merge by first column
设p=h[r[0]];
if(p){p[1].push(r[1]);p[2].push(r[2])};
如果(!p){h[r[0]=[r[0],[r[1]],[r[2]],i]}
});     
让result=Object.values(h).sort((a,b)=>a[3]-b[3]);
result.forEach(r=>{r[1]=[…新集(r[1])];r[2]=[…新集(r[2])])];//删除第二列和第三列中的重复项
返回结果;
}
函数genTable(行,tbody){
设b=“”,x=“”;
rows.forEach(r=>{
x=r.map((c,i)=>`c}`).slice(0,3);
b+=`${x.join(''')}`;
})
tbody.innerHTML=b;
log({b,rows,tbody});
}
函数myFunction(){
let table=document.querySelector('table');
设tbody=table.tBodies[table.tBodies.length-1];
genTable(合并行(可读(tbody)),tbody);
}
表格{
字体系列:arial,无衬线;
边界塌陷:塌陷;
宽度:100%;
}
th{
背景:#A9A9;
}
运输署,
th{
边框:1px实心#dddddd;
文本对齐:居中;
填充:8px;
字体系列:monospace;
字号:17px;
}
.黑暗{
背景色:#dddddd;
}

单位
接触
有限公司