需求:要求做一张表格,表头第一栏有斜线分割,且分割线也要跟随表格自适应
思路:因为之前用了CSS去写,但是发现,只能实现固定的长和宽,如果页面伸缩,斜线就会破版,跟th或者td衔接不上。因此转而将目标锁定在了 canvas 上面,想通过 canvas 来实现自适应的效果。
首先,给第一栏的第一个td 或者th 设置position: relative; 然后在里面嵌套一个 canvas 并设置其样式为 absolute;定义好canvas 的ID值,方便之后获取DOM。具体方法如下示例代码。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>tst</title>
</head>
<style type="text/css">
table {
border-collapse: collapse;
}
table tr th:first-child {
position:relative;
}
canvas {
position:absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
th,td {
width: 200px;
height: 50px;
border: 1px solid black;
}
</style>
<body>
<table>
<tr>
<th>
<em>姓名</em>
<em>性别</em>
<canvas id="myCanvas"></canvas>
</th>
<th></th>
<th></th>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<table>
<tr>
<th>
<em>姓名</em>
<em>性别</em>
<canvas id="myCanvas1"></canvas>
</th>
<th></th>
<th></th>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
</body>
</html>
<script type="text/javascript">
function tableLine(id, coordinate=[{x:1, y:1}], lineLength = 1) {
// 获取DOM节点
var canvas = document.getElementById(id);
// 构建二维画布
var context = canvas.getContext('2d');
// 获取画布的宽高
// 画布尺寸,用以后面连线定位坐标
var caWidth = canvas.width, caHeight = canvas.height;
// 每次执行方法之前,先清除画布
context.clearRect(0,0,500,500);
var x1 = 0, y1 = 0; // 起始点坐标
// 只有一条对角线的情况
// width 和 height 应该都是乘以需要定位到的 宽高比例
var x2, y2;
// 判断有几条连线
if (lineLength === 1) {
x2 = parseInt(caWidth*coordinate[0].x);
y2 = parseInt(caHeight*coordinate[0].y);
// 确定坐标以后还是连线
context.moveTo(x1, y1);
context.lineTo(x2, y2);
} else {
// 循环连线
for (let i=0; i < lineLength; i++) {
x2 = parseInt(caWidth*coordinate[i].x);
y2 = parseInt(caHeight*coordinate[i].y);
// 确定坐标以后还是连线
context.moveTo(x1, y1);
context.lineTo(x2, y2);
}
}
// 设置连线的颜色
context.strokeStyle = "#000";
// 连线
context.stroke();
// 头尾相接
context.closePath();
// 虽然没什么用,但是清空画布很有用,没有他清空不了。
context.beginPath();
// 画布背景色
context.fillStyle = "rgb(255,233,217)";
// api (x, y, width, height)
context.fillRect(0,0,10,10);
context.closePath();
}
// 初始化
tableLine('myCanvas', [{x:0.48, y:1}, {x:1, y:0.56}], 2);
tableLine('myCanvas1');
// tableLine('myCanvas2', [{x:0.88, y:1}, {x:1, y:0.46}], 2);
// 定义一个变量,用于传入函数节流的回调中
function table() {
tableLine('myCanvas', [{x:0.48, y:1}, {x:1, y:0.56}], 2);
tableLine('myCanvas1');
// tableLine('myCanvas2', [{x:0.88, y:1}, {x:1, y:0.46}], 2);
}
// 再定义一个函数节流方法,来减少高频触发事件而优化性能
function throttle(fn, time) {
// 定义一个标记
let flag = true;
// 闭包
return function (e) {
if (!flag) return;
flag = false;
setTimeout(() => {
fn.apply(this, arguments);
flag = true;
}, time)
}
}
window.addEventListener('resize', throttle(table, 300))
</script>
后面加入了函数节流,来减少性能的损耗。
公众号:Coder 杂谈,欢迎关注