通过点击表格行实现单选、全选

效果图

不管三七二十一,一图走天下,如下:

应用场景

更好的用户体验,不需要精准的点击小小的CheckBox实现单选全选

html

    <div class="table-box">
        <table>
            <thead>
                <tr class="check-all">
                    <th>
                        <input type="checkbox">
                    </th>
                    <th>标题</th>
                    <th>标题</th>
                    <th>标题</th>
                    <th>标题</th>
                </tr>
            </thead>
            <tbody id="table"></tbody>
        </table>
    </div>

css

    .table-box{width: 500px; height: 800px; margin: 200px auto;}
    table {width: 100%; border-collapse: collapse;}
    table td, table th{text-align: center; padding: 10px 0;}
    tr:hover{background: lightblue; cursor: pointer;}

js

let table = $('#table');

for (let i = 0; i < 5; i++) {   //循环插入tr
    let tr = $('<tr></tr>');
    tr.append('<td><input type="checkbox"></td>');
    for (let j = 0; j < 4; j++) {   //循环插入td
        tr.append('<td>内容</td>')
    }
    table.append(tr);
}

$('.check-all').click(function() {

    let checkall = $(this).find('input');
    let checkBtn = $('#table').find('input');

    if (checkall[0].checked) {      //判断全选按钮的 checked 值,点击 tr 改变它的 checked
        checkall.prop('checked', false);
    } else {
        checkall.prop('checked', true);
    }

    checkBtn.prop('checked', checkall[0].checked);      //将单选按钮的 checked 值设为全选按钮的 checked 值
})

$('#table').on('click', 'tr', function() {
    let inputChild = $(this).find('input');

    let len = $(this).parents('#table').find('input').length;   //按钮总长度

    if (inputChild[0].checked) {    //判断每一行按钮的 checked 值,点击该行改变它的 checked
        inputChild.prop('checked', false);
    } else {
        inputChild.prop('checked', true);
    }

    let inputCheckAll = $(this).parents('#table').find('input:checked').length;     //获取选中的按钮长度(ps:放在此处,确保获取的选中个数是对的)

    if (inputCheckAll === len) {    //判断 选中的按钮长度 是否等于 按钮总长度,选中全选按钮
        $('.check-all').find('input').prop('checked', true);
    } else {
        $('.check-all').find('input').prop('checked', false);
    }
    console.log(inputCheckAll);
    console.log(len);
})

结束

实现原理不做过多说明,js中注释写的很清晰。

2023-08-06:补充一个完善版

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .table-box {
            width: 500px;
            height: 800px;
            margin: 20px auto;
            user-select: none;
        }

        input {
            width: 16px;
            height: 16px;
        }

        table {
            width: 100%;
            border-collapse: collapse;
        }

        table td, table th {
            text-align: center;
            padding: 10px 0;
        }

        tr:hover {
            background: lightblue;
            cursor: pointer;
        }
    </style>
</head>
<body>
<div class="table-box">
    <table>
        <thead>
        <tr class="check-all-row">
            <th>
                <input type="checkbox">
            </th>
            <th>标题</th>
            <th>标题</th>
            <th>标题</th>
            <th>标题</th>
        </tr>
        </thead>
        <tbody id="tbody"></tbody>
    </table>
</div>

<script>
    const $ = selector => document.querySelector(selector)
    const $2 = selector => document.querySelectorAll(selector)

    const tbody = $('#tbody')
    // 全选行
    const checkAll = $('.check-all-row')
    // 全选行内的 input
    const checkAllInput = checkAll.querySelector('input')

    // 生成布局
    Array.from({length: 5}).forEach(() => {
        const tr = '<td><input type="checkbox"></td>' + '<td>内容</td>'.repeat(4)
        tbody.insertAdjacentHTML('afterbegin', tr)
    })

    // 所有的单选行
    const rows = [...$2('#tbody tr')]
    const rowsSize = rows.length
    // 所有单选行内的 input
    const inputs = rows.map(tr => tr.querySelector('input'))

    // 点击全选行的操作
    function clickCheckAll() {
        const checkedSize = inputs.filter(input => input.checked).length
        checkAllInput.indeterminate = checkedSize && checkedSize !== rowsSize
        checkAllInput.checked = checkedSize === rowsSize
    }

    function setInputsChecked(checked) {
        inputs.forEach(input => input.checked = checked)
    }

    // 点击 全选行
    checkAll.onclick = function ({target}) {
        // 判断是否是 input 元素冒泡触发的事件
        if (target.nodeName === 'INPUT') {
            return setInputsChecked(target.checked)
        }

        const checked = !checkAllInput.checked
        checkAllInput.checked = checked
        setInputsChecked(checked)
    }

    rows.forEach(tr => {
        // 点击单选行
        tr.onclick = function ({target}) {
            // 判断是否是 input 元素冒泡触发的事件
            if (target.nodeName === 'INPUT') {
                return clickCheckAll()
            }

            const input = this.querySelector('input')
            input.checked = !input.checked

            clickCheckAll()
        }
    })
</script>
</body>
</html>

点击查看效果icon-default.png?t=N6B9https://code.juejin.cn/pen/7264165801375039523

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

帝尊菜鸟

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

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

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

打赏作者

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

抵扣说明:

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

余额充值