原生 js 实现 table 标签拖拽表头

原生 js 实现 table 标签拖拽表头

在最新项目开发中遇到一个需求拖拽表头并且实现拿到的数据按拖拽后的顺序传递给后端。

$(function () {
    var d1 = new dragTable();
    d1.init({
        // 初始化table标签的类名或者id名
        tabel: '.Reports',
    });
});

function dragTable() {
    this.disX = 0; // 相对按下的位置移动的距离
    this.outX = 0; // 鼠标按下的点到大盒子边上的距离
    this.lanX = 0; // 拖动到的位置
    this.$createDiv = null;
    this.$createDivBg = null;
    this.clickEv = null;
    this.set = {
        tabel: '.Report',
    };
}

dragTable.prototype.init = function (opt) {
    $.extend(this.set, opt);

    this.$createDiv = $('<div class="createDiv"></div>'); // 底部选中拖拽文字显示
    this.$createDivBg = $('<div class="createDivBg"></div>'); // 防止复制页面的文字;
    this.events();
};
dragTable.prototype.events = function () {
    // 找到table标签的所有th
    var $th = $(this.set.tabel).find('th');
    var that = this;
    // 鼠标按下事件
    $(document).on('mousedown', this.set.tabel + ' th', function (e) {
        that.clickEv = this;
        that.mousedown(this, e);
        that.$createDivBg.show();
    });
    // 鼠标抬起事件
    $(document).on('mouseup', this.set.tabel + ' th,.createDiv,.createDivBg', function (e) {
        that.mouseup(this, e);
    });
};
dragTable.prototype.mousedown = function (that, e) {
    $('body').append(this.$createDiv, this.$createDivBg);
    this.$createDiv.html($(that).html()).hide();

    // 设置选定元素背景颜色
    e.target.style.backgroundColor = 'rgba(55, 147, 248,0.4)';

    this.outX = e.pageX - $(that).offset().left;
    var initX = e.pageX;
    var that = this;
    $(document).on('mousemove', function (ev) {
        that.mousemove(that, initX, ev);
    });
};

dragTable.prototype.mousemove = function (that, initX, ev) {
    this.disX = ev.pageX - initX;
    this.lanX = ev.pageX;
    this.$createDiv.css({ top: ev.pageY - 20, left: ev.pageX - 10 });
    this.getCurrentTh('move');
    Math.abs(this.disX) > 4 ? this.$createDiv.show() : this.$createDiv.hide();
};

dragTable.prototype.mouseup = function (that, ev) {
    $(document).unbind('mousemove');
    // 清除所有样式
    this.resetTable();
};

dragTable.prototype.resetTable = function () {
    this.$createDiv.remove();
    this.$createDivBg.remove();
    this.getCurrentTh('up');
    this.lanX = 0;
    this.disX = 0; // 重置disX
    this.showBorder('all', { 'border-color': '#d8d8d8' });
    // 清除指定元素的背景颜色
    $(this.set.tabel + ' th').css({ 'background-color': '' });
};

// 用于获取th设置位置
dragTable.prototype.getCurrentTh = function (type) {
    var that = this;
    $(this.set.tabel + ' th').each(function (index, item) {
        var l = $(item).offset().left;
        var r = $(item).offset().left + $(item).width();

        if (that.lanX > l && that.lanX < r) {
            that.showBorder(index, { 'border-color': '#d8d8d8' });
            if (that.disX > 4) {
                // 右
                that.showBorder(index, { 'border-right': '2px solid #3793f8' });
                type == 'up' ? that.setThTd(index, 'after') : '';
            }
            if (that.disX < -4) {
                // 左边
                that.showBorder(index - 1, { 'border-right': '2px solid #3793f8' });
                type == 'up' ? that.setThTd(index, 'before') : '';
            }
        } else {
            that.showBorder(index, { 'border-color': '#d8d8d8' });
        }
    });
};

dragTable.prototype.setThTd = function (newsindex, type) {
    var oldIndex = $(this.clickEv).index(); // 是拖拽时的初始坐标,newsindex拖拽结束的坐标

    var $th = $(this.set.tabel + ' th').eq(oldIndex);
    $(this.set.tabel + ' th')
        .eq(newsindex)
        [type]($th.clone());
    $th.remove();
    $(this.set.tabel + ' tbody tr').each(function (index, tdelement) {
        var $td = $(tdelement).find('td').eq(oldIndex);
        $(tdelement).find('td').eq(newsindex)[type]($td.clone());
        $td.remove();
    });
};

dragTable.prototype.showBorder = function (newsindex, css) {
    if (newsindex == 'all') {
        $(this.set.tabel + ' th').css(css);
        $(this.set.tabel + ' td').css(css);
        return;
    }
    $(this.set.tabel + ' th')
        .eq(newsindex)
        .css(css);
    $(this.set.tabel + ' tbody tr').each(function (index, tdelement) {
        $(tdelement).find('td').eq(newsindex).css(css);
    });
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Hoki802

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

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

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

打赏作者

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

抵扣说明:

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

余额充值