需求:要求做一張表格,表頭第一欄有斜線分割,且分割線也要跟隨表格自適應
思路:因爲之前用了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>
後面加入了函數節流,來減少性能的損耗。