前端-2-全选与反选

话说:

今天好大雪!各位读者,中午好啊。幸亏早上跑了个步,不然又得隔几天啦。这篇博客小结下checkbox的全选与反选,用JavaScript和jQuery方式来实现,具体选择哪种,你喜欢就好。

目录:
checkbox全选与反选


1.效果图
2.代码
3.小结


难度系数:★☆☆☆☆
建议用时:10min

1.效果图

这里写图片描述

2.代码

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core"  prefix="c"%>
<!--Author:Meice 2018年1月27日下午12:11:09 -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- 设置input样式,变大点 -->
<style type="text/css">
    input{
        width:30px;
        height:30px;
    }
</style>


<title>全选与全部选</title>
<!--JavaScript方式实现全选  -->
<script type="text/javascript">
    function checkAll(a) {
        var arrayChecks = document.getElementsByName("chk");
        for(var i=0;i<arrayChecks.length;i++) {
            arrayChecks[i].checked = a.checked;
        }


    }
</script>

<!-- jQuery实现全选-->
<!-- 引入jQuery -->
<script  src="js/jquery-1.8.3.js"></script>
<script type="text/javascript">
    $(function(a) {
        $("#checkAllJQuery").click(function() {
            //alert(this.checked);
            if(this.checked==true) {
                $("input[name='chk2']").each(function() {$(this).prop("checked",true)})//法1
                //$("input[name='chk2']").each(function() {$(this).attr("checked","checked")})//法2
            }else{
                $("input[name='chk2']").each(function() {$(this).prop("checked",false)})//法1
                //$("input[name='chk2']").each(function() {$(this).removeAttr("checked")})//法2
            }
        }) 
    })

</script>




</head>
<body>



<table align="center">



    <tr>
        <td><font style="color:red;font-size:20px;font-weight:bolder">JavaScript方式实现全选</font></td>
        <td>
            <input type="checkbox" id="checkAll" onclick="checkAll(this)">全选
        </td>
    </tr>


    <c:forEach begin="1" end="9" var="i">
        <tr>
            <td>${i }</td>
            <td>
                ${i}<input type="checkbox" name="chk">
            </td>
        </tr>
    </c:forEach>

    <p></p><p></p>








    <tr>
        <td>&nbsp;&nbsp;&nbsp;<font style="color:red;font-size:20px;font-weight:bolder;">jQuery方式实现全选</font>
        </td>
        <td>
            <input type="checkbox" id="checkAllJQuery" onclick="checkAllJQuery(this)">全选
        </td>
    </tr>
    <c:forEach begin="1" end="9" var="i">
        <tr>
            <td>${i}</td>
            <td>
                <input type="checkbox" name="chk2">
            </td>
        </tr>

    </c:forEach>


</table>


</body>
</html>

3.小结


jQuery使用prop属性,attr属性都可以,相信我,都经过测试啦。
二者是有细微区别的:name - property对应 用到的方法attr(“checked”,”checked”) removeAttr(“”)

prop(“checked”,true)
prop(“checked”,false)这个不用刻意记忆,忘记了查API就行,工具嘛。当然记住更好!用起来方便,所以学习本质还是记忆里!


好了,这篇博客比较简短,感觉这里jQuery还没有JavaScript方便,我更倾向于直接用JS.

下期再会!

<think> 我们参考之前的对话历史和引用的内容,来回答用户关于el-table多分页全选功能的问题。 根据引用[1][3][4],我们知道实现跨页全选需要以下步骤: 1. 设置el-table的row-key属性,确保每一行有唯一标识(如id)。 2. 在el-table-column的selection列中设置reserve-selection为true,以保留跨页中的状态。 3. 处理selection-change事件,用于收集中的数据。 4. 实现跨页全选功能时,需要维护一个数组(比如unSelectedIds)来记录手动的数据。当点击跨页全选按钮时,实际上是中除了unSelectedIds以外的所有数据。 但是,由于数据量可能很大,不能一次性加载所有数据,所以不能直接通过前端数据全选。因此,我们需要通过后台配合,记录中的状态,或者通过记录的数据来实现。 具体实现思路如下: - 当用户点击“跨页全选”按钮时,我们设置一个全选状态(例如selectAllFlag=true),并清空当前中的数组(selectedList),同时将之前手动的数据(unSelectedIds)置空。然后,我们向后端请求当前页的数据,并设置当前页的中状态(注意:当前页的数据中,如果有在unSelectedIds中的,则不中)。 - 当用户切换分页时,根据selectAllFlag和unSelectedIds来设置当前页的中状态:如果selectAllFlag为true,则当前页的数据中不在unSelectedIds的项都应该被中。 - 当用户手动某一行时,如果当前处于全选状态(selectAllFlag=true),则将该行的id添加到unSelectedIds中,并将该行从中状态移除;如果不在全选状态,则按照普通的单处理。 - 当用户手动中某一行时,如果当前处于全选状态,实际上该行已经被中,所以这里不需要额外处理;如果不是全选状态,则添加到中数组。 此外,引用[1]提到,为了避免频繁请求接口导致的性能问题,我们可以添加loading和disabled效果。 下面我们结合代码示例来具体说明。 步骤1:设置el-table ```vue <el-table ref="multipleTable" :data="tableData" style="width: 100%" @selection-change="handleSelectionChange" row-key="id" > <el-table-column type="selection" width="55" :reserve-selection="true" /> <!-- 其他列 --> </el-table> ``` 步骤2:定义相关数据 ```javascript data() { return { tableData: [], // 当前页数据 pageNum: 1, // 当前页码 pageSize: 10, // 每页条数 total: 0, // 总条数 selectAllFlag: false, // 是否跨页全选全选所有页) unSelectedIds: [], // 在全选状态下,手动取消择的id集合 selectedList: [], // 当前中的行(包括跨页中的) loading: false // 加载状态 } } ``` 步骤3:跨页全选按钮 ```vue <el-button @click="toggleSelectAll">跨页全选</el-button> ``` 步骤4:跨页全选方法 ```javascript methods: { toggleSelectAll() { if (this.selectAllFlag) { // 如果已经是全选状态,则取消全选 this.selectAllFlag = false; this.unSelectedIds = []; this.selectedList = []; // 取消表格所有中 this.$refs.multipleTable.clearSelection(); } else { // 设置全选状态 this.selectAllFlag = true; this.unSelectedIds = []; // 清空列表 // 这里需要将当前页的数据中,手动取消中的先过滤掉(初始时unSelectedIds为空,所以当前页会全部中) this.setCurrentPageSelected(); // 注意:这里我们只处理了当前页,其他页的数据在切换分页时会通过reserve-selection和下面的方法自动处理 } }, // 设置当前页的中状态 setCurrentPageSelected() { if (this.selectAllFlag) { // 全选状态下,当前页的数据中,不在unSelectedIds中的行都要中 this.$nextTick(() => { this.tableData.forEach(row => { if (!this.unSelectedIds.includes(row.id)) { this.$refs.multipleTable.toggleRowSelection(row, true); } else { this.$refs.multipleTable.toggleRowSelection(row, false); } }); }); } }, // 处理择变化 handleSelectionChange(selection) { // 注意:selection是当前页的所有中行(不包括之前页的中行,因为reserve-selection虽然保留了跨页中的行,但是在selection-change事件中,当前页切换时,事件触发只包含当前页的中行) // 因此,我们需要重新计算中的列表。 // 在全选状态下,我们需要更新selectedList:selectedList = 所有数据(除了unSelectedIds中的) // 但是,我们并不知道所有数据,所以这里我们只记录当前页的变化,并且更新unSelectedIds。 if (this.selectAllFlag) { // 在全选状态下,当前页的selection变化都是由于手动取消中或手动中(之前取消的又回来)造成的。 // 当前页的所有行id const currentPageIds = this.tableData.map(row => row.id); // 当前页应该被中的行id(即不在unSelectedIds中的) const shouldSelectedIds = currentPageIds.filter(id => !this.unSelectedIds.includes(id)); // 实际中的行id const selectedIds = selection.map(row => row.id); // 找出当前页中应该中但未被中的(即用户取消中的) const unSelectedInPage = shouldSelectedIds.filter(id => !selectedIds.includes(id)); // 找出当前页中不应该中却被中的(即用户重新中的,之前是取消的,现在又中了) const reSelectedInPage = selectedIds.filter(id => this.unSelectedIds.includes(id)); // 更新unSelectedIds:将当前页新取消的id添加进去,将当前页重新中的id从unSelectedIds中剔除 this.unSelectedIds = [ ...this.unSelectedIds.filter(id => !reSelectedInPage.includes(id) && !currentPageIds.includes(id)), ...unSelectedInPage ]; // 由于全选状态,所以selectedList理论上应该是所有数据(除了unSelectedIds中的),但我们不知道所有数据,所以这里selectedList我们不用来存储所有中的数据,而是用来存储当前页中的?实际上,我们不需要维护一个完整的selectedList,因为中的状态由selectAllFlag和unSelectedIds就可以确定:中的是除去unSelectedIds的所有数据。 // 但是,如果我们需要在界面上展示中的数量,或者需要提交中的id,我们可以通过selectAllFlag和unSelectedIds以及总条数来计算: // 中的数量 = 总条数 - unSelectedIds.length // 这里我们可以重新设置selectedList为当前selection(因为跨页中的状态由reserve-selection维护,但事件只触发当前页,所以我们不能直接使用selection作为全部中数据) // 实际上,我们并不需要selectedList来存储所有中的数据,因为数据量太大。所以我们通常只记录取消中的id,然后提交给后端时,告诉后端:全选,但排除这些id。 } else { // 非全选状态,直接使用selection作为中的行 this.selectedList = selection; } }, // 加载数据的方法(分页改变时调用) fetchData() { this.loading = true; // 调用接口获取数据 // 假设api.getData返回一个Promise api.getData({ pageNum: this.pageNum, pageSize: this.pageSize }).then(res => { this.tableData = res.list; this.total = res.total; this.loading = false; // 数据加载完成后,设置当前页的中状态 this.setCurrentPageSelected(); }).catch(() => { this.loading = false; }); } } ``` 注意:上面的实现中,我们在全选状态下,通过unSelectedIds来记录取消中的id。这样,当用户点击跨页全选后,我们实际上知道用户排除了哪些数据。在提交时,我们可以这样处理: - 如果是全选状态,那么需要提交的参数是:{ selectAll: true, excludeIds: this.unSelectedIds } - 如果不是全选状态,那么提交中的id数组:{ selectAll: false, selectedIds: this.selectedList.map(row => row.id) } 另外,当分页改变时,我们需要重新设置当前页的中状态(调用setCurrentPageSelected)。因此,在fetchData方法中,数据获取后需要调用this.setCurrentPageSelected()。 关于性能:引用[1]提到,跨页全选会触发接口查询数据,所以我们在分页切换时也会请求接口,但这是正常的分页请求。而全选按钮的点击并不会请求接口,只是改变了状态,然后设置当前页的中状态。所以性能问题主要在于分页请求数据的速度。我们只需要在分页请求时添加loading效果,避免用户频繁操作。 引用[2]提到了使用滚动加载,但用户问题主要是分页全选,所以我们这里以分页为例。 总结:通过以上步骤,我们实现了跨页全选功能,同时保留了el-table原有的单和整页全选功能。 下面我们根据要求生成相关问题: </think> ### el-table实现多分页全选功能的完整方法 实现el-table的多分页全选功能,需要解决跨页数据保持中状态的问题。以下是完整实现步骤(基于Vue 2/3 + Element UI): #### 1. 基础表格配置 ```vue <template> <el-table ref="multipleTable" :data="tableData" row-key="id" // 关键:设置行唯一标识 @selection-change="handleSelectionChange" @select="handleSelect" > <el-table-column type="selection" width="55" :reserve-selection="true" // 关键:保留跨页中 /> <!-- 其他列 --> </el-table> <el-pagination @current-change="handlePageChange" :total="total" /> <el-button @click="toggleSelectAll">跨页全选</el-button> </template> ``` #### 2. 核心数据方法实现 ```javascript export default { data() { return { tableData: [], // 当前页数据 total: 0, // 总数据量 pageSize: 10, // 每页条数 currentPage: 1, // 当前页码 selectedList: [], // 所有中数据 selectAllFlag: false, // 全选状态标识 unSelectedIds: [], // 排除的ID集合 loading: false // 加载状态 } }, methods: { // 加载数据 async loadData() { this.loading = true; const res = await api.getData({ page: this.currentPage, size: this.pageSize }); this.tableData = res.list; this.total = res.total; this.loading = false; this.setPageSelection(); // 设置当前页中状态 }, // 设置当前页中状态 setPageSelection() { this.$nextTick(() => { this.tableData.forEach(row => { if(this.selectAllFlag) { // 全选状态下排除指定ID const isSelected = !this.unSelectedIds.includes(row.id); this.$refs.multipleTable.toggleRowSelection(row, isSelected); } else { // 非全选状态根据selectedList设置 const isSelected = this.selectedList.some(item => item.id === row.id); this.$refs.multipleTable.toggleRowSelection(row, isSelected); } }); }); }, // 跨页全选切换 toggleSelectAll() { if(this.selectAllFlag) { // 取消全选 this.selectAllFlag = false; this.unSelectedIds = []; this.selectedList = []; } else { // 启用全选 this.selectAllFlag = true; this.unSelectedIds = []; this.selectedList = []; } this.setPageSelection(); }, // 处理单操作 handleSelect(selection, row) { if(this.selectAllFlag) { // 全选状态下的手动 if(!selection.includes(row)) { this.unSelectedIds.push(row.id); } else { // 移出排除列表 this.unSelectedIds = this.unSelectedIds.filter(id => id !== row.id); } } else { // 普通中状态 this.selectedList = selection; } }, // 分页切换 handlePageChange(page) { this.currentPage = page; this.loadData(); }, // 获取最终择结果 getSelectedIds() { if(this.selectAllFlag) { return { allSelected: true, excludeIds: this.unSelectedIds }; } else { return { allSelected: false, selectedIds: this.selectedList.map(item => item.id) }; } } } } ``` #### 3. 关键点说明 1. **`row-key`和`reserve-selection`** 必须同时设置这两个属性,确保跨页时能跟踪每行中状态 2. **双模式数据存储** - `selectAllFlag=true`:记录排除项(`unSelectedIds`) - `selectAllFlag=false`:记录中项(`selectedList`) 3. **性能优化** - 添加`loading`状态防止重复请求 - 使用`$nextTick`确保DOM更新后操作 - 批量操作时避免渲染整个列表 4. **数据提交** 通过`getSelectedIds()`方法获取两种模式下的中数据,后端根据`allSelected`标志处理 #### 4. 注意事项 1. 后端API需支持排除ID查询(当`selectAllFlag=true`时) 2. 大数据量场景建议添加防抖操作 3. 使用`el-table-infinite-scroll`可实现滚动加载替代分页[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值