使用phuocng/html-dom实现表格列宽可调整功能

使用phuocng/html-dom实现表格列宽可调整功能

html-dom Common tasks of managing HTML DOM with vanilla JavaScript. Give me 1 ⭐if it’s useful. html-dom 项目地址: https://gitcode.com/gh_mirrors/ht/html-dom

表格是网页开发中常用的数据展示方式,但固定列宽往往无法满足不同数据长度的需求。本文将详细介绍如何使用纯JavaScript实现表格列宽可调整功能,让用户能够通过拖拽轻松调整列宽。

功能概述

我们将实现一个表格列宽调整功能,主要特点包括:

  • 每列右侧显示可拖拽调整的指示器
  • 拖拽时实时调整列宽
  • 拖拽过程中提供视觉反馈
  • 兼容现代浏览器

实现步骤

1. HTML结构准备

首先需要一个基础表格结构,为表格设置一个ID以便后续操作:

<table id="resizeMe" class="table">
    <thead>
        <tr>
            <th>序号</th>
            <th>名字</th>
            <th>姓氏</th>
        </tr>
    </thead>
    <tbody>
        <!-- 表格数据行 -->
    </tbody>
</table>

2. CSS样式设置

为表格和列调整器添加必要的样式:

/* 基础表格样式 */
.table {
    border-collapse: collapse;
    width: 100%;
}
.table th, .table td {
    border: 1px solid #ccc;
    padding: 0.5rem;
    text-align: left;
}

/* 表头相对定位,为调整器提供定位基准 */
.table th {
    position: relative;
}

/* 列调整器样式 */
.resizer {
    position: absolute;
    top: 0;
    right: 0;
    width: 5px;
    height: 100%;
    cursor: col-resize;
    user-select: none;
}

/* 悬停和拖动时的视觉反馈 */
.resizer:hover,
.resizing {
    border-right: 2px solid #1a73e8;
}

3. JavaScript实现

3.1 创建列调整器

首先需要为每个表头列创建并添加调整器元素:

// 获取表格元素
const table = document.getElementById('resizeMe');

// 获取所有表头列
const cols = table.querySelectorAll('th');

// 遍历每个表头列
cols.forEach((col) => {
    // 创建调整器元素
    const resizer = document.createElement('div');
    resizer.classList.add('resizer');
    
    // 设置调整器高度与表格一致
    resizer.style.height = `${table.offsetHeight}px`;
    
    // 将调整器添加到列中
    col.appendChild(resizer);
    
    // 初始化可调整列功能
    createResizableColumn(col, resizer);
});
3.2 实现列宽调整功能

createResizableColumn函数负责处理鼠标事件以实现列宽调整:

function createResizableColumn(col, resizer) {
    let startX = 0;  // 鼠标按下时的X坐标
    let startWidth = 0;  // 列初始宽度

    const mouseDownHandler = function(e) {
        // 记录初始位置和宽度
        startX = e.clientX;
        startWidth = parseInt(window.getComputedStyle(col).width, 10);
        
        // 添加移动和释放事件监听
        document.addEventListener('mousemove', mouseMoveHandler);
        document.addEventListener('mouseup', mouseUpHandler);
        
        // 添加拖动状态类
        resizer.classList.add('resizing');
    };

    const mouseMoveHandler = function(e) {
        // 计算鼠标移动距离
        const distance = e.clientX - startX;
        
        // 更新列宽
        col.style.width = `${startWidth + distance}px`;
    };

    const mouseUpHandler = function() {
        // 移除拖动状态类
        resizer.classList.remove('resizing');
        
        // 移除事件监听
        document.removeEventListener('mousemove', mouseMoveHandler);
        document.removeEventListener('mouseup', mouseUpHandler);
    };

    // 绑定鼠标按下事件
    resizer.addEventListener('mousedown', mouseDownHandler);
}

4. 完整实现

将上述代码整合,并在DOM加载完成后执行:

document.addEventListener('DOMContentLoaded', function() {
    const table = document.getElementById('resizeMe');
    const cols = table.querySelectorAll('th');

    cols.forEach((col) => {
        const resizer = document.createElement('div');
        resizer.classList.add('resizer');
        resizer.style.height = `${table.offsetHeight}px`;
        col.appendChild(resizer);
        createResizableColumn(col, resizer);
    });

    function createResizableColumn(col, resizer) {
        let startX = 0;
        let startWidth = 0;

        const mouseDownHandler = function(e) {
            startX = e.clientX;
            startWidth = parseInt(window.getComputedStyle(col).width, 10);
            document.addEventListener('mousemove', mouseMoveHandler);
            document.addEventListener('mouseup', mouseUpHandler);
            resizer.classList.add('resizing');
        };

        const mouseMoveHandler = function(e) {
            const distance = e.clientX - startX;
            col.style.width = `${startWidth + distance}px`;
        };

        const mouseUpHandler = function() {
            resizer.classList.remove('resizing');
            document.removeEventListener('mousemove', mouseMoveHandler);
            document.removeEventListener('mouseup', mouseUpHandler);
        };

        resizer.addEventListener('mousedown', mouseDownHandler);
    }
});

功能优化建议

  1. 最小宽度限制:为防止列宽过小,可以设置最小宽度限制
  2. 性能优化:对于大型表格,可以使用防抖技术减少重绘次数
  3. 触摸屏支持:添加触摸事件处理以支持移动设备
  4. 列宽记忆:使用localStorage保存用户调整后的列宽

常见问题解答

Q: 为什么调整器有时不工作? A: 确保表格布局不是自动布局,可以设置表格宽度为100%或固定值。

Q: 如何实现多列表格调整? A: 上述代码已经支持多列表格,会自动为每个表头列添加调整器。

Q: 调整列宽会影响其他列吗? A: 当前实现是独立调整每列宽度,如需联动调整,需要额外计算其他列宽。

通过以上实现,我们创建了一个用户友好的可调整列宽表格,提升了数据展示的灵活性。这种实现方式纯前端完成,无需后端支持,适合各种Web应用场景。

html-dom Common tasks of managing HTML DOM with vanilla JavaScript. Give me 1 ⭐if it’s useful. html-dom 项目地址: https://gitcode.com/gh_mirrors/ht/html-dom

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

农烁颖Land

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值