效果如下
原表格:
col0 |
col1 |
col2 |
col3 |
SuZhou |
11111 |
22222 |
SuZhouCity |
SuZhou |
33333 |
44444 |
SuZhouCity |
SuZhou |
55555 |
66666 |
SuZhouCity |
ShangHai |
77777 |
88888 |
ShangHaiCity |
ShangHai |
uuuuu |
hhhhh |
ShangHaiCity |
ShangHai |
ggggg |
ccccc |
ShangHaiCity |
GuangZhou |
ttttt |
eeeee |
GuangZhouCity |
GuangZhou |
ppppp |
qqqqq |
GuangZhouCity |
处理之后的样子:
col0 |
col1 |
col2 |
col3 |
SuZhou |
11111 |
22222 |
SuZhouCity |
33333 |
44444 |
55555 |
66666 |
ShangHai |
77777 |
88888 |
ShangHaiCity |
uuuuu |
hhhhh |
ggggg |
ccccc |
GuangZhou |
ttttt |
eeeee |
GuangZhouCity |
ppppp |
qqqqq |
效果出来, 看上去比较简单, 下面先看下页面
col0 |
col1 |
col2 |
col3 |
SuZhou |
11111 |
22222 |
SuZhouCity |
SuZhou |
33333 |
44444 |
SuZhouCity |
SuZhou |
55555 |
66666 |
SuZhouCity |
ShangHai |
77777 |
88888 |
ShangHaiCity |
ShangHai |
uuuuu |
hhhhh |
ShangHaiCity |
ShangHai |
ggggg |
ccccc |
ShangHaiCity |
GuangZhou |
ttttt |
eeeee |
GuangZhouCity |
GuangZhou |
ppppp |
qqqqq |
GuangZhouCity |
// 这里写成了一个jquery插件的形式
$('#process').mergeCell({
// 目前只有cols这么一个配置项, 用数组表示列的索引,从0开始
// 然后根据指定列来处理(合并)相同内容单元格
cols: [0, 3]
});
下面看看这个小插件的完整代码:
;(function($) {
// jquery 소스 코드를 살펴본 후 $.fn이 $.prototype임을 알 수 있습니다. jQuery는 이전 버전의 플러그와의 호환성을 위해서만 유지됩니다. -in
// 프로토타입의 형태
$.fn.mergeCell = function(options) {
return this.each(function() {
var cols = options.cols;
for ( var i = cols.length - 1; cols[i] != 정의되지 않음; i--) {
// 콘솔 디버깅 수정
// console.debug(cols[i])
mergeCell($(this), cols [i]);
}
dispose($(this))
})
}// 확실히 이해했다면 JavaScript의 클로저와 범위 개념 중 내부적으로 사용되는 Private 메소드 플러그인입니다
// 자세한 내용은 이전 에세이에서 소개한 책을 참조하세요
function mergeCell($table, colIndex) {
$table.data('col-content', ''); // 셀 내용 저장
$table.data('col-rowspan', 1) // 계산된 rowspan 값 저장, 기본값은 다음과 같습니다. 1
$table.data('col-td' , $()); // 이전 행과 다른 발견된 첫 번째 td(jQuery로 캡슐화됨)를 저장하고 기본값은 "빈" jquery 객체입니다.
$table.data('trNum', $( 'tbody tr', $table).length); //처리할 테이블의 총 행 수, 마지막 행이 특수 처리되는지 판단하는 데 사용됩니다.
//핵심은 데이터의 각 행을 "스캔"하는 것입니다. 이는 col-td와 해당 행 범위를 찾는 것입니다.
$('tbody tr', $table).each(function(index) {
// td:eq의 colIndex는 열 인덱스입니다.
var $td = $('td:eq(' colIndex ')', this)
// 셀의 현재 내용을 가져옵니다.
var currentContent = $td.html();
// 먼저 다음 번에 이 분기를 가져옵니다.
if ($table.data('col-content') == '') {
$ table.data('col-content', currentContent);
$table.data('col-td', $td);
} else {
// 이전 행의 내용은 다음과 같습니다. 현재 행
if ($table.data('col-content') == currentContent) {
// 이전 행의 내용이 현재 행과 동일하면 col-rowspan이 누적되고 새 값이 저장됩니다.
var rowspan = $table.data('col-rowspan') 1
$table.data(' col-rowspan', rowspan)// 주목할 가치가 있습니다. $td.remove()를 사용하면 다른 열의 처리에 영향을 미칩니다.
$td.hide()
// 마지막 줄의 상황은 조금 특별합니다
// 예를 들어 마지막 두 줄의 td 내용이 동일하다면 이때 col-td에 저장된 td는 마지막 줄의 rowspan으로 설정해야 합니다.
if ( index = = $table.data(' trNum'))
$table.data('col-td').attr('rowspan', $table.data('col-rowspan'))
} else { // 이전 행이 현재 행과 다릅니다
// col-rowspan의 기본값은 1입니다. 계산된 col-rowspan이 변경되지 않은 경우 처리되지 않습니다.
if ($table.data('col-rowspan' ) != 1) {
$table.data('col-td').attr('rowspan', $table.data('col-rowspan'))
}
// 저장 첫 번째 다른 콘텐츠가 포함된 td와 해당 콘텐츠가 나타나면 col-rowspan
$table.data('col-td', $td)
$table.data('col-content', $ td.html());
$table.data('col-rowspan', 1);
}
}
})
}
// 메모리 정리 함수
function dispose($table) {
$table.removeData();
}
})(jQuery)
주요 지침 코드는 비교적 간단하지만 개선이 필요한 부분이 있습니다
처리할 테이블 내용은 tbody부터 검색됩니다.
for ( var i = cols.length - 1; cols[i] != undefine; i--)... 테이블 데이터의 양이 많고 처리할 컬럼이 많은 경우 여기서 최적화가 실패합니다. 브라우저 스레드가 차단될 위험이 있으니 setTimeout 사용을 고려해 보세요
개선할 만한 다른 사항도 있지만 꽤 많이 있을 것 같습니다