Giả sử rằng chúng tôi muốn thay đổi kích thước bất kỳ cột nào trong bảng sau:
<table id="resizeMe" class="table">
    ...
</table>

Chuẩn bị:

Đối với mỗi cột, tôi chèn một phần tử div cho biết rằng cột được liên kết có thể thay đổi kích thước. Phần tử thay đổi kích thước được định vị hoàn toàn bên trong cột. Các kiểu CSS cho chúng sẽ như sau:
.table th {
    position: relative;
}
.resizer {
    /* Displayed at the right side of column */
    position: absolute;
    top: 0;
    right: 0;
    width: 5px;
    cursor: col-resize;
    user-select: none;
}
Để tạo thay đổi kích thước và nối chúng vào các cột, chúng ta phải truy vấn và lặp qua tất cả các cột:
// Query the table
const table = document.getElementById('resizeMe');

// Query all headers
const cols = table.querySelectorAll('th');

// Loop over them
[].forEach.call(cols, function (col) {
    // Create a resizer element
    const resizer = document.createElement('div');
    resizer.classList.add('resizer');

    // Set the height
    resizer.style.height = `${table.offsetHeight}px`;

    // Add a resizer element to the column
    col.appendChild(resizer);

    // Will be implemented in the next section
    createResizableColumn(col, resizer);
});

Xử lý các sự kiện của resizer

Chúng ta sẽ triển khai một hàm createResizableColumn nhận hai tham số:
  • col đại diện cho tiêu đề bảng
  • resizer đại diện cho phần tử thay đổi kích thước trong cột.
Để cho phép người dùng thay đổi kích thước col, chúng tôi phải xử lý ba sự kiện:
  • mousedown trên resizer: Theo dõi vị trí hiện tại của chuột
  • mousemove trên document: Tính xem chuột đã di chuyển được bao xa và điều chỉnh độ rộng của cột
  • mouseup trên document: Xóa trình xử lý sự kiện của document
const createResizableColumn = function (col, resizer) {
    // Track the current position of mouse
    let x = 0;
    let w = 0;

    const mouseDownHandler = function (e) {
        // Get the current mouse position
        x = e.clientX;

        // Calculate the current width of column
        const styles = window.getComputedStyle(col);
        w = parseInt(styles.width, 10);

        // Attach listeners for document's events
        document.addEventListener('mousemove', mouseMoveHandler);
        document.addEventListener('mouseup', mouseUpHandler);
    };

    const mouseMoveHandler = function (e) {
        // Determine how far the mouse has been moved
        const dx = e.clientX - x;

        // Update the width of column
        col.style.width = `${w + dx}px`;
    };

    // When user releases the mouse, remove the existing event listeners
    const mouseUpHandler = function () {
        document.removeEventListener('mousemove', mouseMoveHandler);
        document.removeEventListener('mouseup', mouseUpHandler);
    };

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

Làm nổi bật resizer

Chúng tôi có thể cải thiện trải nghiệm người dùng một chút. Khi người dùng di chuột hoặc nhấp vào bộ thay đổi kích thước, nó có thể được tô sáng. Để thể hiện ý tưởng theo cách đơn giản nhất, chúng tôi thêm một đường viền cố định vào :hover :
.resizer:hover,
.resizing {
    border-right: 2px solid blue;
}
Lớp resizing được thêm vào resizer trong khi người dùng nhấp và kéo resizer:
const mouseDownHandler = function(e) {
    ...
    resizer.classList.add('resizing');
};

const mouseUpHandler = function() {
    ...
    resizer.classList.remove('resizing');
};

See the Pen Untitled by Mr.Control (@phucuong13029x) on CodePen.