<!DOCTYPE html PUBLIC "-//W4C//DTD XHTML 1.0 Transitional//EN"
"http://www.w4.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<META http-equiv=content-Type content="text/html; charset=utf-8">
<style>
#tbl {
border-collapse: collapse;
}
#tbl td {
border: 1px solid black;
}
.ui-selected {
background: limegreen;
}
</style>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
<table ondragstart="return false;" onselectstart="return false;" id="tbl" cellspacing="1" cellpadding="5">
<tr>
<td>标题一</td>
<td>标题二</td>
<td>标题三</td>
<td>标题四</td>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
<td>D</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>T</td>
<td>X</td>
<td>Y</td>
<td>U</td>
</tr>
</table>
<script>
//获取头部td集合
var tblObj = document.getElementById("tbl");
let t_row_num = tblObj.rows.length;
for (let i = 0; i < t_row_num; i++) {
//只有rows这个能选,col要先选rows,然后用cells
let t_cell_num = tblObj.rows[i].cells.length;
for (let j = 0; j < t_cell_num; j++) {
let t_cell = tblObj.rows[i].cells[j];
addListener(t_cell, "mousedown", on_td_mousedown);
// addListener(t_cell, "mousemove", on_td_mousemove);
}
}
let g_mousedown_resize_type = ''; //鼠标按下时的方向, 是 col,还是 row
let g_mousedown_row_index = ''; //鼠标按下时的行号
let g_mousedown_col_index = ''; //鼠标按下时的列号
var g_td_resizeable = false;
var g_target_td;
var screenYStart = 0;
var screenXStart = 0;
var g_td_height = 0;
var g_td_width = 0;
var headerHeight = 0;
function on_td_mousedown(event) {
if (!g_td_resizeable) {
return;
}
var evt = event || window.event;
// g_mousedown = true;
let t_src_obj = getTarget(evt);
console.log('on_td_mousemove t_src_obj');
console.log(t_src_obj);
console.log('cellIndex=' + t_src_obj.cellIndex);
let t_cursor = t_src_obj.style.cursor;
console.log('t_cursor=' + t_cursor);
g_mousedown_resize_type = '';
if ('col-resize' == t_cursor) {
g_mousedown_resize_type = 'col-resize';
} else {
g_mousedown_resize_type = 'row-resize';
}
screenYStart = evt.screenY;
screenXStart = evt.screenX;
if (g_target_td) {
g_td_height = g_target_td.offsetHeight;
g_td_width = g_target_td.offsetWidth;
}
headerHeight = tblObj.offsetHeight;
}
document.onmouseup = function (event) {
tartgetTd = null;
coltargetTd = null;
g_td_resizeable = false;
// g_mousedown = false;
colmousedown = false;
colresizeable = false;
g_mousedown_resize_type = '';
document.body.style.cursor = 'default';
}
document.onmousemove = function (event) {
var evt = event || window.event;
var t_src_obj = getTarget(evt);
console.log('on_td_mousemove t_src_obj');
console.log(t_src_obj);
let t_row_index = t_src_obj.parentNode.rowIndex;
let t_col_index = t_src_obj.cellIndex;
console.log('rowIndex=' + t_row_index);
console.log('cellIndex=' + t_col_index);
let t_cursor = t_src_obj.style.cursor;
console.log('t_cursor=' + t_cursor);
//rowIndex是未定义!!!cellIndex是好用的。我应该获取的是tr的rowindex
//获取偏移 这里是鼠标的偏移
var offsetY = evt.offsetY;
var offsetX = evt.offsetX;
console.log('offsetY=' + offsetY);
if (g_mousedown_resize_type) {
if (!g_target_td) {
console.log('g_target_td 为空');
} else if ('col-resize' == g_mousedown_resize_type) {
let t_width = (g_td_width + (evt.screenX - screenXStart)) + "px"; //计算后的新的宽度
g_target_td.style.width = t_width;
let t_row_num = tblObj.rows.length;
for (let i = 0; i < t_row_num; i++) {
//对每一行的单元格都要修改宽度
let t_cell = tblObj.rows[i].cells[g_mousedown_col_index];
t_cell.style.width = t_width;
}
} else if ('row-resize' == g_mousedown_resize_type) {
let t_delta_y = (evt.screenY - screenYStart);
let t_height = (g_td_height + t_delta_y) + "px"; //计算后的新的宽度
console.log('g_td_height=' + g_td_height + ', t_height=' + t_height)
console.log('screenYStart=' + screenYStart + ', evt.screenY=' + evt.screenY + ', t_delta_y=' + t_delta_y);
g_target_td.style.height = t_height;
let t_col_num = tblObj.rows[0].cells.length;
//对这一行的每一列的单元格都要修改高度
for (let i = 0; i < t_col_num; i++) {
let t_cell = tblObj.rows[g_mousedown_row_index].cells[i];
t_cell.style.height = t_height;
}
tblObj.style.height = (headerHeight + (evt.screenY - screenYStart)) + "px";
}
} else {
g_mousedown_row_index = t_row_index;
g_mousedown_col_index = t_col_index;
if (t_row_index >= 0 && t_src_obj.offsetHeight - evt.offsetY <= 8) {
//在单元格内部靠近底部框,实际改变本单元格
console.log('在单元格内部靠近底部框,实际改变本单元格');
g_target_td = t_src_obj;
g_td_resizeable = true;
t_src_obj.style.cursor = 'row-resize';//修改光标样式
} else if (t_src_obj.offsetWidth - evt.offsetX <= 8) {
console.log('右边!!!!');
//靠近单元格右边边框时,实际改变本单元格
g_target_td = t_src_obj;
g_td_resizeable = true;
t_src_obj.style.cursor = 'col-resize';//修改光标样式
} else if (t_row_index > 0 && evt.offsetY <= 8) {
console.log('在单元格内部靠近顶部框,实际改变上一行的单元格');
g_mousedown_row_index = t_src_obj.parentNode.rowIndex - 1;
let targetTr = tblObj.rows[g_mousedown_row_index];
if (targetTr) {
g_target_td = targetTr.cells[t_src_obj.cellIndex];
}
g_td_resizeable = true;
t_src_obj.style.cursor = 'row-resize';
} else if (t_col_index > 0 && evt.offsetX <= 8) {
console.log('左边!!!!');
console.log('t_row_index=' + t_row_index);
let targetTr = tblObj.rows[t_row_index];
if (targetTr) {
g_mousedown_col_index = t_col_index == 0 ? 0 : t_col_index - 1;
g_target_td = targetTr.cells[g_mousedown_col_index];
} else {
console.log('targetTr为空==========');
}
// console.log('g_mousedown_col_index=='+g_mousedown_col_index);
// console.log('g_target_td==');
// console.log(g_target_td);
g_td_resizeable = true;
t_src_obj.style.cursor = 'col-resize';
} else {
g_mousedown_resize_type = '';
g_td_resizeable = false;
t_src_obj.style.cursor = 'default';
}
}
}
function getTarget(evt) {
return evt.target || evt.srcElement;
}
function addListener(element, type, listener, useCapture) {
//这是两种写法,对应不同浏览器
element.addEventListener ? element.addEventListener(type, listener, useCapture) : element.attachEvent("on" + type, listener);
}
$(function () {
$('#tbl td').click(function () {
if ($(this).hasClass("ui-selected")) {
$('.ui-selected').removeClass('ui-selected');
} else {
$('.ui-selected').removeClass('ui-selected');
$(this).addClass('ui-selected');
}
});
});
</script>
</body>
</html>
合并单元格的拖动:
<!DOCTYPE html PUBLIC "-//W4C//DTD XHTML 1.0 Transitional//EN"
"http://www.w4.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<META http-equiv=content-Type content="text/html; charset=utf-8">
<style>
#tbl {
border-collapse: collapse;
}
#tbl td {
border: 1px solid black;
}
.ui-selected {
background: limegreen;
}
</style>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
<button onclick="show_table()">显示表格内容</button>
<table id="tbl" cellspacing="1" cellpadding="5">
<tr>
<td colspan="3" >标题一</td>
<!--<td>标题二</td>-->
<!--<td>标题二</td>-->
<!--<td>标题三</td>-->
<td>标题四</td>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
<td>D</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>A</td>
<!--<td>X</td>-->
<td>X</td>
<td>X</td>
<td>U</td>
</tr>
</table>
<script>
//获取头部td集合
var tblObj = document.getElementById("tbl");
let t_row_num = tblObj.rows.length;
for (let i = 0; i < t_row_num; i++) {
//只有rows这个能选,col要先选rows,然后用cells
let t_cell_num = tblObj.rows[i].cells.length;
for (let j = 0; j < t_cell_num; j++) {
let t_cell = tblObj.rows[i].cells[j];
addListener(t_cell, "mousedown", on_td_mousedown);
// addListener(t_cell, "mousemove", on_td_mousemove);
}
}
let g_mousedown_resize_type = ''; //鼠标按下时的方向, 是 col,还是 row
let g_mousedown_row_index = ''; //鼠标按下时的行号
let g_mousedown_col_index = ''; //鼠标按下时的列号
var g_td_resizeable = false;
var g_target_td;
var screenYStart = 0;
var screenXStart = 0;
var g_td_height = 0;
var g_td_width = 0;
var headerHeight = 0;
let g_arr_real_td = [];
$(function () {
g_arr_real_td = checkRealTd();
})
//检查Td是否真实存在,真实存在的是1,虚拟的td,即被跨行、跨列干掉的单元格的是0
function checkRealTd() {
var tblObj = document.getElementById("tbl");
let t_row_num = tblObj.rows.length;
let t_max_cell_num = 0;
for (let i = 0; i < t_row_num; i++) {
//只有rows这个能选,col要先选rows,然后用cells
let t_cell_num = tblObj.rows[i].cells.length;
if (t_cell_num > t_max_cell_num) {
t_max_cell_num = t_cell_num;
}
}
let arr_real_td = [];
//先初始化
for (let i = 0; i < t_row_num; i++) {
arr_real_td[i] = [];
for (let j = 0; j < t_max_cell_num; j++) {
arr_real_td[i][j] = 1;
}
}
for (let i = 0; i < t_row_num; i++) {
let t_row = tblObj.rows[i];
console.log('i=' + i);
for (let j = 0; j < t_max_cell_num; j++) {
//找到这一行开头有多少个虚拟的td
let t_v_td_num = 0;
for (let v = 0; v < j; v++) {
if (0 == arr_real_td[i][v]) {
t_v_td_num++;
}
}
let t_real_j = j - t_v_td_num;
let t_cell = t_row.cells[t_real_j];
console.log('j=' + j + ', t_v_td_num=' + t_v_td_num);
if (!t_cell) {
console.log('元素不存在 ');
continue;
}
if (0 == arr_real_td[i][j]) {
continue;
}
let t_rowSpan = t_cell.rowSpan;
let t_colSpan = t_cell.colSpan;
if (1 == t_rowSpan && 1 == t_colSpan) {
continue;
}
console.log(' t_rowSpan=' + t_rowSpan + ', t_colSpan=' + t_colSpan);
for (let rs = 0; rs < t_rowSpan; rs++) {
for (let cs = 0; cs < t_colSpan; cs++) {
arr_real_td[i + rs][t_real_j + cs] = 0;
}
}
arr_real_td[i][t_real_j] = 1;
}
}
console.log('t_row_num=' + t_row_num + ', t_max_cell_num=' + t_max_cell_num);
console.log('arr_real_td==');
console.log(arr_real_td);
return arr_real_td;
}
function show_table() {
console.log(tblObj);
console.log('rows===');
console.log(tblObj.rows);
console.log('cells===');
for (let i in tblObj.rows) {
console.log(tblObj.rows[i].cells);
}
checkRealTd();
}
function on_td_mousedown(event) {
if (!g_td_resizeable) {
return;
}
var evt = event || window.event;
// g_mousedown = true;
let t_src_obj = getTarget(evt);
console.log('on_td_mousemove t_src_obj');
console.log(t_src_obj);
console.log('cellIndex=' + t_src_obj.cellIndex);
let t_cursor = t_src_obj.style.cursor;
console.log('t_cursor=' + t_cursor);
g_mousedown_resize_type = '';
if ('col-resize' == t_cursor) {
g_mousedown_resize_type = 'col-resize';
} else {
g_mousedown_resize_type = 'row-resize';
}
screenYStart = evt.screenY;
screenXStart = evt.screenX;
if (g_target_td) {
g_td_height = g_target_td.offsetHeight;
g_td_width = g_target_td.offsetWidth;
}
headerHeight = tblObj.offsetHeight;
}
document.onmouseup = function (event) {
tartgetTd = null;
coltargetTd = null;
g_td_resizeable = false;
// g_mousedown = false;
colmousedown = false;
colresizeable = false;
g_mousedown_resize_type = '';
document.body.style.cursor = 'default';
}
document.onmousemove = function (event) {
var evt = event || window.event;
var t_src_obj = getTarget(evt);
// console.log('on_td_mousemove t_src_obj');
// console.log(t_src_obj);
let t_row_index = t_src_obj.parentNode.rowIndex;
let t_col_index = t_src_obj.cellIndex;
// console.log('rowIndex=' + t_row_index);
// console.log('cellIndex=' + t_col_index);
let t_cursor = t_src_obj.style.cursor;
// console.log('t_cursor=' + t_cursor);
//rowIndex是未定义!!!cellIndex是好用的。我应该获取的是tr的rowindex
//获取偏移 这里是鼠标的偏移
var offsetY = evt.offsetY;
var offsetX = evt.offsetX;
// console.log('offsetY=' + offsetY);
if (g_mousedown_resize_type) {
if (!g_target_td) {
// console.log('g_target_td 为空');
} else if ('col-resize' == g_mousedown_resize_type) {
console.log('rowIndex=' + t_row_index);
console.log('cellIndex=' + t_col_index);
let t_width = (g_td_width + (evt.screenX - screenXStart)) + "px"; //计算后的新的宽度
g_target_td.style.width = t_width;
let t_col_span = g_target_td.colSpan;
let t_row_span = g_target_td.rowSpan;
console.log('t_col_span=' + t_col_span);
let t_row_num = tblObj.rows.length;
if (t_col_span > 1) {
//当这个单元格是合并单元格时,只改自己的宽度
let t_cell = tblObj.rows[t_row_index].cells[t_col_index];
if (t_cell) {
t_cell.style.width = t_width;
}
} else {
//对每一行的这个单元格都要修改宽度
for (let i = 0; i < t_row_num; i++) {
//虚拟td数量
let t_v_td_num = 0;
for (let ri = 0; ri < t_col_index; ri++) {
if (0 == g_arr_real_td[i][ri]) {
t_v_td_num++;
}
}
let t_real_col_index = t_v_td_num + t_col_index;
console.log('i=' + i + ', t_v_td_num=' + t_v_td_num);
if (0 == g_arr_real_td[i][t_real_col_index]) {
console.log('i=' + i + ', t_real_col_index=' + t_real_col_index + ', 是虚拟td');
continue;
}
//对每一行的这个单元格都要修改宽度
let t_cell = tblObj.rows[i].cells[t_real_col_index];
if (t_cell) {
t_cell.style.width = t_width;
}
}
}
} else if ('row-resize' == g_mousedown_resize_type) {
let t_delta_y = (evt.screenY - screenYStart);
let t_height = (g_td_height + t_delta_y) + "px"; //计算后的新的宽度
// console.log('g_td_height=' + g_td_height + ', t_height=' + t_height)
// console.log('screenYStart=' + screenYStart + ', evt.screenY=' + evt.screenY + ', t_delta_y=' + t_delta_y);
g_target_td.style.height = t_height;
let t_col_num = tblObj.rows[0].cells.length;
//对这一行的每一列的单元格都要修改高度
let t_row_span = g_target_td.rowSpan;
if (1 == t_row_span) {
for (let i = 0; i < t_col_num; i++) {
let t_cell = tblObj.rows[g_mousedown_row_index].cells[i];
if (t_cell) {
t_cell.style.height = t_height;
}
}
}
tblObj.style.height = (headerHeight + (evt.screenY - screenYStart)) + "px";
}
} else {
g_mousedown_row_index = t_row_index;
g_mousedown_col_index = t_col_index;
if (t_row_index >= 0 && t_src_obj.offsetHeight - evt.offsetY <= 8) {
//在单元格内部靠近底部框,实际改变本单元格
// console.log('在单元格内部靠近底部框,实际改变本单元格');
g_target_td = t_src_obj;
g_td_resizeable = true;
t_src_obj.style.cursor = 'row-resize';//修改光标样式
} else if (t_src_obj.offsetWidth - evt.offsetX <= 8) {
// console.log('右边!!!!');
//靠近单元格右边边框时,实际改变本单元格
g_target_td = t_src_obj;
g_td_resizeable = true;
t_src_obj.style.cursor = 'col-resize';//修改光标样式
} else if (t_row_index > 0 && evt.offsetY <= 8) {
// console.log('在单元格内部靠近顶部框,实际改变上一行的单元格');
g_mousedown_row_index = t_src_obj.parentNode.rowIndex - 1;
let targetTr = tblObj.rows[g_mousedown_row_index];
if (targetTr) {
g_target_td = targetTr.cells[t_src_obj.cellIndex];
}
g_td_resizeable = true;
t_src_obj.style.cursor = 'row-resize';
} else if (t_col_index > 0 && evt.offsetX <= 8) {
// console.log('左边!!!!');
// console.log('t_row_index=' + t_row_index);
let targetTr = tblObj.rows[t_row_index];
if (targetTr) {
g_mousedown_col_index = t_col_index == 0 ? 0 : t_col_index - 1;
g_target_td = targetTr.cells[g_mousedown_col_index];
} else {
// console.log('targetTr为空==========');
}
// console.log('g_mousedown_col_index==' + g_mousedown_col_index);
// console.log('g_target_td==');
// console.log(g_target_td);
g_td_resizeable = true;
t_src_obj.style.cursor = 'col-resize';
} else {
g_mousedown_resize_type = '';
g_td_resizeable = false;
t_src_obj.style.cursor = 'default';
}
}
}
function getTarget(evt) {
return evt.target || evt.srcElement;
}
function addListener(element, type, listener, useCapture) {
//这是两种写法,对应不同浏览器
element.addEventListener ? element.addEventListener(type, listener, useCapture) : element.attachEvent("on" + type, listener);
}
$(function () {
$('#tbl td').click(function () {
if ($(this).hasClass("ui-selected")) {
$('.ui-selected').removeClass('ui-selected');
} else {
$('.ui-selected').removeClass('ui-selected');
$(this).addClass('ui-selected');
}
});
});
</script>
</body>
</html>