element table 实现鼠标拖拽选中

父组件

<template>
    <div id=‘add‘>
        <airtable
            :tableData="tableData"
            :columData="columData"
            :menuList ="menuList"
            :pageTotal="pageTotal"
            @rowContextmenu="rowContextmenu"
            @currentPageChange="currentPageChange"
            @handleSelect="handleSelect"
        >
            <template slot=date slot-scope="scope">
                <!--把所有的数据都变成插槽导出-->
                <div class="air-table-slot__div">{{scope.row.date}}</div>
            </template>
            <template slot=name slot-scope="scope">
                <!--把所有的数据都变成插槽导出-->
                <div class="air-table-slot__div">{{scope.row.name}}</div>
            </template>
            <template slot=address slot-scope="scope">
                <!--把所有的数据都变成插槽导出-->
                <div class="air-table-slot__div">{{scope.row.address}}</div>
            </template>
        </airtable>
    </div>
</template>
<script>
import airtable from "@/components/newCommon/table/table.vue";
export default {
    components: {
        airtable
    },
    name: ‘text-form‘,
    data() {
        return {
            columData:[
                {
                    name: ‘时间‘,
                    key: ‘date‘,
                    isFixed: true,//固定列参数
                    width:"auto"
                },
                {
                    name: ‘名字‘,
                    key: ‘name‘,
                    isFixed: true,//固定列参数
                    width:"auto"
                },
                {
                    name: ‘地址‘,
                    key: ‘address‘,
                    isFixed: true,//固定列参数
                    width:"auto"
                },
            ],
            //table 表头字段数据
            tableData: [

            ],
            //这个是右键的按钮操作
            menuList:[{icon:"air-icon-moreapps",name:"操作"},{icon:"air-icon-moreapps",name:"曾加"},{icon:"air-icon-moreapps",name:"修改"}],
            //从后台获得的分页的总数
            pageTotal:100
        }
    },
    methods: {
        //鼠标右键菜单点击事件 传出来的是要做的操作和当前的列
        rowContextmenu(item,row){
            console.log(item,row);
        },
        //监听当前页的变化
        currentPageChange(currentpage){
            console.log(currentpage);
        },
        //当鼠标批量编辑时或者点击鼠标选中时触发 传来的是选中的列表数据
        handleSelect(multipleSelection){
            console.log(multipleSelection)
        }
    },
    watch: {

    },
    created(){
        for(var i=0;i<20;i++){
            this.tableData.push({
                date: ‘2016-05-03‘,
                name: ‘王小虎‘,
                address: ‘上海市普陀区金沙江路 1518 弄dddddddddddddddddddddddddddd‘,
                id:i
            })
        }
    }
}

</script>

<style>
#add {
    height:100%;
}
.el-carousel__item h3 {
    color: #475669;
    font-size: 18px;
    opacity: 0.75;
    line-height: 300px;
    margin: 0;
}

.el-carousel__item:nth-child(2n) {
    background-color: #99a9bf;
}

.el-carousel__item:nth-child(2n + 1) {
    background-color: #d3dce6;
}
.mengban {
    position: fixed;
    border: 1px solid rgb(0, 119, 255);
    background-color: rgba(0, 119, 255, 0.3);
    -moz-user-select: none;
    -khtml-user-select: none;
    user-select: none;
}
tbody{
    position: relative;
}
.air-table-slot__div {
    min-width: 200px;
    max-width: 300px;
    overflow: hidden;/*超出部分隐藏*/
    white-space: nowrap;/*不换行*/
    text-overflow:ellipsis;/*超出部分文字以...显示*/
}
</style>

  子组件table

<template>
    <div class=‘air-table-wrapper‘>
        <el-table
            ref="table"
            :show-header="true"
            :data="tableData"
            tooltip-effect="dark"
            style="width: 100%;"
            :header-row-class-name="headerClassName"
            :height="‘500‘"
            id="table"
            @row-click="rowClick"
            @row-contextmenu="rowContextmenu"
            v-drag>
            <el-table-column  :type="isType" width="55" align="center"></el-table-column>
            <!--列表的表头循环-->
            <el-table-column
                v-for="(column, index) in columData"
                :key="index"
                :label="column.name"
                :width="column.width">
                <template slot-scope="scope">
                    <!--把所有的数据都变成插槽导出-->
                    <slot :name="column.key" :row="scope.row"> </slot>
                </template>
            </el-table-column>
            <template slot=append>
                <div :class="[‘el-table__append-page‘]">
                    <el-pagination
                        @size-change="handleSizeChange"
                        @current-change="handleCurrentChange"
                        :current-page.sync="currentPage"
                        :page-size="20"
                        layout="total, prev, pager, next"
                        :total="pageTotal">
                    </el-pagination>
                </div>
            </template>
        </el-table>
        <air-contex-menu
            :position="position"
            :toggleShow="toggleShow"
            :menuList="menuList"
            @menuClick="menuClick"
        ></air-contex-menu>
    </div>
</template>
<script>
import airContexMenu from ‘./contextMenu.js‘;
export default {
    name: ‘airtable‘,
    // 框选的指令
    directives: {
        drag: {
            // 指令的定义
            inserted: function (el, binding, vnode) {
                var oDiv = el;
                //监听用户鼠标事件
                oDiv.onmousedown = function (ev) {
                    //初始化不显示
                    vnode.context.toggleShow=false;
                    //确保用户在移动鼠标的时候只初始化一次选中
                    var flag = true;
                    //用来存储列表
                    var selList = [];
                    //获得指令下的dom对应的表格
                    var fileNodes = oDiv.getElementsByTagName("tr");
                    var countI = 0;
                    //获得鼠标
                    var evt = window.event || arguments[0];
                    var startX = (evt.x || evt.clientX);
                    var startY = (evt.y || evt.clientY);
                    var top,left;
                    //时时获得
                    top=getY(oDiv);
                    left=getX(oDiv);
                    var selDiv = document.createElement("div");
                    selDiv.style.cssText = "position:absolute;width:0px;height:0px;font-size:0px;margin:0px;padding:0px;border:1px dashed #0099FF;background-color:#C3D5ED;z-index:1000;filter:alpha(opacity:60);opacity:0.6;display:none;";
                    selDiv.id = "selectDiv";
                    document.getElementsByClassName("el-table__body")[0].appendChild(selDiv);
                    selDiv.style.left = startX + "px";
                    selDiv.style.top = startY + "px";
                    var _x = null;
                    var _y = null;
                    vnode.context.clearEventBubble(evt);
                    // //打开开关
                    vnode.context.mouseflag = true;
                    // //鼠标拖动时画框
                    document.onmousemove = function (ev) {
                        evt = window.event || arguments[0];
                        _x = (evt.x || evt.clientX);
                        _y = (evt.y || evt.clientY);
                        //为了确定是点击事件还是移动事件
                        if(Math.abs(_x - startX)<5 && Math.abs(_y - startY)<5){
                            return;
                        }
                        //为了确保只有一次的渲染每次框选都把默认选中为空
                        if(flag){
                            //重置选中css
                            for (var i = 0; i < fileNodes.length; i++) {
                                if (fileNodes[i].className.indexOf("el-table__row") != -1) {
                                    fileNodes[i].className = "el-table__row";
                                    selList.push(fileNodes[i]);
                                }
                            }
                            vnode.context.multipleSelection=[]
                            vnode.context.tableData.forEach((ele)=>{
                                vnode.context.$refs.table.toggleRowSelection(ele,false)
                            })
                            flag = false;
                        }
                        if (vnode.context.mouseflag) {
                            if (selDiv.style.display == "none") {
                                selDiv.style.display = "";
                            }
                            var scrolling=oDiv.getElementsByClassName("is-scrolling-none");
                            selDiv.style.left = Math.min(_x, startX)-left+scrolling[0].scrollLeft + "px";
                            //48是表头的高度
                            selDiv.style.top = Math.min(_y, startY)-top - 48+scrolling[0].scrollTop+ "px";
                            selDiv.style.width = Math.abs(_x - startX) + "px";
                            selDiv.style.height = Math.abs(_y - startY) + "px";

                            // ---------------- 关键算法确定列表的选中靠的是index---------------------
                            var _l = selDiv.offsetLeft, _t = selDiv.offsetTop;
                            var _w = selDiv.offsetWidth, _h = selDiv.offsetHeight;
                            for (var i = 0; i < selList.length; i++) {
                                var sl = selList[i].offsetWidth + selList[i].offsetLeft;
                                var st = selList[i].offsetHeight + selList[i].offsetTop;
                                if (sl > _l && st > _t && selList[i].offsetLeft < _l + _w && selList[i].offsetTop < _t + _h) {
                                    if (selList[i].className.indexOf("seled") == -1) {
                                        selList[i].className = selList[i].className + " seled";
                                        vnode.context.$refs.table.toggleRowSelection(vnode.context.tableData[i],true)
                                        //把选中的都存入到table标签中的已选中
                                        if(vnode.context.tableData[i])
                                            vnode.context.multipleSelection.push(vnode.context.tableData[i]);
                                    }
                                } else {
                                    if (selList[i].className.indexOf("seled") != -1 ) {
                                        selList[i].className = "el-table__row";
                                        vnode.context.$refs.table.toggleRowSelection(vnode.context.tableData[i],false);
                                        vnode.context.multipleSelection.forEach((ele,i)=>{
                                            //这里没用对象是否相等用的是传入table中的唯一的myKey字段
                                            if(ele[vnode.context.myKey]==vnode.context.tableData[i][vnode.context.myKey] ){
                                                vnode.context.multipleSelection.splice(i,1);
                                            }
                                        })
                                    }
                                }
                            }

                        }
                        vnode.context.clearEventBubble(evt);
                    };
                    //方法是确定列表到屏幕的位置
                    function getX(obj){
                        var parObj=obj;
                        var left=obj.offsetLeft;
                        while(parObj=parObj.offsetParent){
                            left+=parObj.offsetLeft;
                        }
                        return left;
                    }
                    //方法是确定列表到屏幕的位置
                    function getY(obj){
                        var parObj=obj;
                        var top=obj.offsetTop;
                        while(parObj = parObj.offsetParent){
                            top+=parObj.offsetTop;
                        }
                        return top;
                    }
                    //在鼠标抬起后做的重置
                    document.onmouseup = function () {
                        //把鼠标移动事初始化
                        document.onmousemove=null;
                        if (selDiv) {
                            document.getElementsByClassName("el-table__body")[0].removeChild(selDiv);
                        }
                        selList = null, _x = null, _y = null, selDiv = null, startX = null, startY = null, evt = null;
                        vnode.context.mouseflag = false;
                        vnode.context.$handleSelect();
                    };
                };
            }
        }
    },
    components: {
        airContexMenu,
    },
    props: {
        //对于列表中唯一的字段myKey默认为id
        myKey: {
            type: String,
            default: "id"
        },
        //列表的数据
        tableData: {
            type: Array,
            default: () => []
        },
        //传过来的表头信息
        columData: {
            type: Array,
            default: () => []
        },
        //有没有checkbox
        isType : {
            type: String,
            default: "selection"
        },
        //右键菜单
        menuList:{
            type: Array,
            default: () => []
        },
        //分页的总页数
        pageTotal:{
            type:Number,
            default: 0
        }
    },
    data() {
        return {
            //指令中确定的时候是鼠标按下事件
            mouseflag: false,
            //选中的数组
            multipleSelection: [],
            //控制右键菜单弹出显示
            dialogVisible:false,
            //右键鼠标的位置
            position:{
                left:0,
                top:0
            },
            //控制右键显示隐藏
            toggleShow :false,
            //分页当前的页数
            currentPage:1 ,
            //当前右键点击的列
            currentRow:[],
            //当前滚动的距离,
            targetScroll:0
        }
    },
    methods: {
        //清除默认事件
        clearEventBubble(evt) {
            if (evt.stopPropagation)
                evt.stopPropagation();
            else
                evt.cancelBubble = true;
            if (evt.preventDefault)
                evt.preventDefault();
            else
                evt.returnValue = false;
        },
        //列表单击选中事件
        rowClick(row, event, column) {
            let flag=true;
            //确定当前的row的index
            var index = 0;
            this.tableData.forEach((ele,i)=>{
                if(ele[this.myKey] == row[this.myKey]){
                    index = i+1;
                }
            })
            this.toggleShow = false;
            //如果有就移除
            this.multipleSelection.forEach((ele,i)=>{
                if(ele[this.myKey]==row[this.myKey]){
                    this.$refs.table.toggleRowSelection(row,false);
                    //后期优化吧 element的方法用不了 只能自己改变类名
                    this.$refs.table.$el.getElementsByTagName("tr")[index].className = "el-table__row";
                    this.multipleSelection.splice(i,1);
                    flag = false;
                }
            })
            //如果没有就push
            if(flag){
                this.$refs.table.toggleRowSelection(row,true);
                this.multipleSelection.push(row);
                //后期优化吧 element的方法用不了 只能自己改变类名
                this.$refs.table.$el.getElementsByTagName("tr")[index].className = "el-table__row seled";
            }
        },
        //列表右键点击事件
        rowContextmenu(row, event){
            //为当前的row赋值
            this.currentRow = row;
            //阻止默认右键点击事件
            event.returnValue = false;
            //获取右键坐标
            this.position.left = event.clientX
            this.position.top = event.clientY
            //菜单出现的flag
            this.toggleShow = true;
            //显示弹出窗
        },
        //右键菜单弹出事件
        menuClick(item){
            //右键点击以后隐藏
            this.toggleShow=false;
            this.$emit("rowContextmenu",item,this.currentRow)
        },
        //每页条数变化 ui定死每页20条
        handleSizeChange(val) {
            // console.log(`每页 ${val} 条`);
        },
        //当前页变化
        handleCurrentChange(val) {
            this.currentPage = val;
            this.$emit(‘currentPageChange‘,this.currentPage)
        },
        //当批量选中结束调用
        $handleSelect(){
            this.$emit(‘handleSelect‘,this.multipleSelection)
        },
        //监听表格的滚动
        handleScroll(e){
            this.targetScroll = e.target.scrollTop;
        },
        //
        headerClassName(){
            return "air-table-header__class";
        }
    },
    computed: {

    },
    created() {

        //确保右键菜单消失
        document.onclick = ()=>{
            this.toggleShow=false;
        }
    },
    mounted() {

    }
}

</script>

<style lang="scss">
    @import "../../../public/style/mixin.scss";

    .air-table-wrapper {
        @include wh(100%, 100%);
        .seled {
            background: #f5f5f5 !important;
        }
        .no-seled{
            background: #ffffff !important;
        }
        .el-table__body tr{
            cursor: pointer;
            box-sizing: border-box;
            border-top:1px solid #f5f5f5;
            border-bottom:1px solid #f5f5f5;
        }
        .air-table-header__class th{
            border-bottom:1px solid #f5f5f5 !important;
        }
        .el-table__body td{
            border-bottom:1px solid #f5f5f5;
        }
        .hover-row {
            border-top:1px solid #f5f5f5;
            border-bottom:1px solid #f5f5f5;
            background: #fafafa;
        }
        .el-table__append-page{
            padding-top:48px;
            padding-bottom:48px;
            .el-pagination{
                text-align: right;
            }
        }
        .el-table__append-info{
            position: absolute;
            bottom:0px;
            width:100%;
            .el-pagination{
                text-align: right;
            }
        }
        .air-table__context--menu{
            box-shadow:0 3px 5px -1px rgba(0,0,0,.2), 0 6px 10px 0 rgba(0,0,0,.14), 0 1px 18px 0 rgba(0,0,0,.12);
            .air-table__context--list {
                cursor: pointer;
                height: 48px;
                @include flexCenter(flex-start,center);
                .air-table__context--icon{
                    font-size: 14px;
                    margin-left:20px;
                    color:#757575;
                }
                .air-table__context--info{
                    font-size: 14px;
                    margin-left:20px;
                    color:#212121;
                }
            }
            .air-table__context--list:hover{
                background: #f5f5f5;
            }
        }

    }
</style>

  子组件中的右键菜单组件

export default {
    name: ‘airContexMenu‘,
    props: {
        position: {
            type: Object,
            default: () => {
                return {
                    top: 0,
                    left: 0
                }
            }
        },
        toggleShow:{
            type:Boolean,
            default: false
        },
        menuList : {
            type: Array,
            default: () => []
        }
    },
    render(h) {
        var self = this;
        var menuInfo = [];
        this.menuList.forEach((ele)=>{
            menuInfo.push(h(‘li‘,{
                style: {
                    width:"100%",
                    display:"flex"
                },
                class: [‘air-table__context--list‘,‘ripple‘],
                on: {
                        click:function (){
                            self.$emit(‘menuClick‘, ele)
                        }
                    }
                },
            [
                h(‘i‘, {
                    class: [ele.icon,‘air-table__context--icon‘]
                }),
                h(‘span‘,{class:[‘air-table__context--info‘]}, ele.name)
            ]))
        })
        return h(
            ‘div‘, {
                style: {
                  width:"300px",
                  padding: "8px 0px",
                  position:"fixed",
                  left: this.position.left + "px",
                  top: this.position.top + "px",
                  display: this.toggleShow ? "block" : "none",
                  zIndex:99999,
                  backgroundColor:"#fff",
                  borderRadius:"4px"
                },
                class: [‘air-table__context--menu‘]
            },
            menuInfo
        );
    },
    computed: {

    },
    data() {
        return {

        };
    },
    created() {

    },
    methods: {
        menuClick(){

        }
    }
};

  

原文地址:https://www.cnblogs.com/smallteeth/p/9382529.html

时间: 2024-08-30 12:54:58

element table 实现鼠标拖拽选中的相关文章

CSS禁用鼠标拖拽选中内容

chrome  -webkit-user-select:none firxfox  -moz-user-select:none IE需要使用JS的onSelected事件了. JS代码 dom.style.MozUserSelect = 'none';//fixrox禁止选择的JS脚本            dom.style.webkitUserSelect = 'none';            if( document.all ){//IE下禁止选择                dom

Xcode如何拖拽选中文字、拖拽代码

不管是文本编辑,还是代码工具,一般都提供了用鼠标拖拽选中文字到指定地方的功能,但是在Xcode里貌似这样有点儿难,你会发现当想拖动的时候会有时候成功,但是大部分时间都是又处于选择状态.一开始我以为是Mac系统的原因,后来发现在其他地方:浏览器就可以拖动,我想这可能是Xcode里去掉了,但是有时候能拖拽是怎么回事.好吧,我不coding了,非得找出来. 废话不多说了: 点击选中的代码(文字),不要移动和松开鼠标左键,当竖线变成箭头之后就可以拖动了,其实不需要多少时间,基本上就是:不要直接点鼠标左键

JS组件系列——Bootstrap Table 表格行拖拽

原文:JS组件系列--Bootstrap Table 表格行拖拽 前言:之前一直在研究DDD相关知识,好久没更新JS系列文章了.这两天做了一个简单的业务需求,觉得效果还可以,今天在这里分享给大家,欢迎拍砖~~ 一.业务需求及实现效果 项目涉及到订单模块,那天突然接到一个需求,说是两种不同状态的订单之间要实现插单的效果,页面上呈现方式是:左右两个Table,左边Table里面是状态为1的订单,右边Table里面是状态为2订单,左边Table里面的行数据拖动到右边Table里面指定行的位置,拖动完成

鼠标拖拽多选功能

<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>鼠标拖拽多选功能</title> <script src="https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script> <style type="text/css"&

js实现鼠标拖拽多选功能

最近做了一个用js实现鼠标拖拽多选的功能,于是整理了一下思路,写了一个小demo:遮罩出现:被遮罩盖住的,即为选中的块(背景色为粉色)下面是具体代码,注释已在文中,与大家交流. <!DOCTYPE html> <html> <head> <title>鼠标拖拽多选功能</title> <script src="https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js">

JavaScript鼠标拖拽特效及相关问题总结

#div1{width:200px;height:200px;background:red;position:absolute;} #div2{width:200px;height:200px;background:green;position:absolute;left:300px;} <div id="div1">原来的 普通拖拽</div> <div id="div2">继承的 限制范围拖拽</div> wind

unity 鼠标拖拽物体实现任意角度自旋转

主要涉及函数 Input.GetAxis(“Mouse x”) 可取得鼠标横向(x轴)移动增量 Input.GetAxis(“Mouse y”) 可取得鼠标竖向(y轴)移动增量 通过勾股定理获取拖拽长度,长度越长旋转越快 在project setting--Input 可以设置 直接上代码,看了就明白了 1 using UnityEngine; 2 using System.Collections; 3 4 public class startRoate : MonoBehaviour 5 {

一款基于jQuery的支持鼠标拖拽滑动焦点图

记得之前我们分享过一款jQuery全屏广告图片焦点图,图片切换效果还不错.今天我们要分享另外一款jQuery焦点图插件,它的特点是支持鼠标拖拽滑动,所以在移动设备上使用更加方便,你只要用手指滑动屏幕即可切换图片. 在线预览   源码下载 实现的代码. html代码: <div class="main_visual"> <div class="flicking_con"> <a class="on" href=&quo

js实现鼠标拖拽div-------Day44

如果去问这样一个问题"你觉得鼠标操作简单,还是键盘操作简单",相信会有多数人都会回答鼠标吧,毕竟键盘按钮那么多,如果手小了或者手法不规范了,太容易出问题了,也对操作的速度和有效性是大大的降低了,当然不可否认,会有那么一批人,操作起键盘来完全可以忽略鼠标的,但这些都应该是骨灰级别的了吧,起码我现在的层次还接触不到,只能向往. 然而,当面对这么一个问题时,我突然有点纠结,因为毕竟以前我也是那么想的,但是这次开发让我是大跌眼镜,键盘操作我在开发中,我只能判定其按键是否按键,然后根据不同按键进