table表頭斜線自適應

需求:要求做一張表格,表頭第一欄有斜線分割,且分割線也要跟隨表格自適應

思路:因爲之前用了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>

後面加入了函數節流,來減少性能的損耗。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章