Table按住Shift多选(Javascript)


一般的多选,我们会给用户很多的checkbox,让用户挨个点击,我们可以做一个优化,像PC一样,按住Shift可以多选。

Shift多选事件

按住Shift多选,还需要判断是否处于按住的情况,直接调用原生的onkeydown、onkeyup,会多出很多乱七八糟的代码,这里进行一个简单的封装。

/**
     * Shift多选事件,注意需要调用unbind()解绑
     *
     * E.G.:
     * var shiftClickEvent = new ShiftClickEvent({
     *         onkeydown: function () {
     *        },
     *         onkeyup: function () {
     *        }
     *    });
     */
    function ShiftClickEvent(opts) {
        var isPressing = false;
        document.onkeydown = function (event) {
            event.preventDefault();
            var e = event || window.event || arguments.callee.caller.arguments[0];
            if (isPressing === false && e && e.keyCode === 16) {
                isPressing = true;
                if (opts.onkeydown !== undefined) {
                    opts.onkeydown();
                }
            }
        };
        document.onkeyup = function (event) {
            event.preventDefault();
            var e = event || window.event || arguments.callee.caller.arguments[0];
            if (e && e.keyCode === 16) {
                isPressing = false;
                if (opts.onkeyup !== undefined) {
                    opts.onkeyup();
                }
            }
        };
        return {
            isPressingShift: function () {
                // 是否按住Shift按键
                return isPressing;
            },
            unbind: function () {
                document.onkeydown = undefined;
                document.onkeyup = undefined;
            }
        }
    }

Css样式

/**
 * 去除浏览器默认的Shift多选效果
 */
.cannot-select {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
/**
 * 点击高亮
 */
.mul-table-click{
    background-color: lightyellow;
}
/**
 * 单选高亮
 */
.mul-table-select{
    background-color: lightyellow;
}
/**
 * 多选高亮
 */
.high-light-multi{
    background-color: lightgray;
}

JQuery控件封装

(function () {
    /**
     * Shift多选事件,注意需要unbind()事件
     *
     * var shiftClickEvent = new ShiftClickEvent({
     *         onkeydown: function () {
     *        },
     *         onkeyup: function () {
     *        }
     *    });
     */
    function ShiftClickEvent(opts) {
        var isPressing = false;
        document.onkeydown = function (event) {
            event.preventDefault();
            var e = event || window.event || arguments.callee.caller.arguments[0];
            if (isPressing === false && e && e.keyCode === 16) {
                isPressing = true;
                if (opts.onkeydown !== undefined) {
                    opts.onkeydown();
                }
            }
        };
        document.onkeyup = function (event) {
            event.preventDefault();
            var e = event || window.event || arguments.callee.caller.arguments[0];
            if (e && e.keyCode === 16) {
                isPressing = false;
                if (opts.onkeyup !== undefined) {
                    opts.onkeyup();
                }
            }
        };
        return {
            isPressingShift: function () {
                return isPressing;
            },
            unbind: function () {
                document.onkeydown = undefined;
                document.onkeyup = undefined;
            }
        }
    }

    function MultiSelectTable(options) {
        var table = options.el;
        table.addClass('mul-table-cannot-select');
        var trList = [], currentData = [];

        // Shift多选,需要记住前一次点击的行,和正在点击的行
        var preClickRow = -1, curClickRow = -1;
        // Shift事件
        var shiftClickEvent = new ShiftClickEvent({
            onkeydown: function () {
                preClickRow = -1;
                for (var i = 0; i < trList.length; i++) {
                    trList[i].removeClass('mul-table-multi');
                }
            },
            onkeyup: function () {
                if (preClickRow === -1) {
                    curClickRow = -1;
                }
                if (curClickRow !== -1) {
                    if (curClickRow < preClickRow) {
                        curClickRow = preClickRow + curClickRow;
                        preClickRow = curClickRow - preClickRow;
                        curClickRow = curClickRow - preClickRow;
                    }
                    highLightRowByRange(preClickRow, curClickRow);
                    options.onMultiSelect(preClickRow, curClickRow);
                }
            }
        });

        // 行点击事件
        function bindEvent(tr, data, i) {
            tr.click(function (evt) {
                if (shiftClickEvent.isPressingShift()) {
                    //按住Shift的时候,不触发点击事件
                    preClickRow = curClickRow;
                    curClickRow = i;
                } else {
                    //高亮点击行
                    curClickRow = i;
                    highLightRow(i);
                    options.onClickRow(data, i);
                }
            });
        }

        // 渲染数据列表(值得改造的代码,可以用模版引擎优化)
        function render(list) {
            currentData = list;
            if (list !== undefined) {
                for (var i = 0; i < list.length; i++) {
                    var ele = list[i];
                    var tr = $('<tr id="grid-' + i + '"><td>' + ele[options.textField] + '</td></tr>');
                    bindEvent(tr, ele, i);
                    trList.push(tr);
                    tr.appendTo(table);
                }
            }
        }

        /**
         * 高亮选中的行
         * @param start 开始行
         * @param end   结束行
         */
        function highLightRowByRange(start, end) {
            for (var i = 0; i < trList.length; i++) {
                var ele = trList[i];
                ele.removeClass('mul-table-click');
                if (i >= start && i <= end) {
                    ele.addClass('mul-table-multi');
                } else {
                    ele.removeClass('mul-table-multi');
                }
            }
        }

        /**
         * 高亮选中的行
         * @param id 行号
         */
        function highLightRow(id) {
            var idStr = 'grid-' + id;
            for (var j = 0; j < trList.length; j++) {
                var ele = trList[j];
                ele.removeClass('mul-table-multi');
                if (idStr === trList[j].attr('id')) {
                    ele.addClass('mul-table-click');
                } else {
                    ele.removeClass('mul-table-click');
                }
            }
        }

        /**
         * 选中行,通过Js直接选中某一行(选中的时候,不移除多选的css样式)
         * @param id
         */
        function selectRow(id) {
            var idStr = 'grid-' + id;
            for (var j = 0; j < trList.length; j++) {
                var ele = trList[i];
                if (idStr === trList[j].attr('id')) {
                    ele.addClass('mul-table-select');
                    options.onClickRow(currentData[j], j);
                } else {
                    ele.removeClass('mul-table-select');
                }
            }
        }


        return {
            selectRow: selectRow,
            render: render,
            destroy: function () {
                //控件销毁
                table.empty();
                trList = [];
                shiftClickEvent.unbind();
            }
        }
    }

    window.MultiSelectTable = MultiSelectTable;
})();

使用以及效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<link href="./mul-table.css" rel="stylesheet" type="text/css"/>
<body>
<table id="table"></table>
</body>
<script src="../jquery.js" type="application/x-javascript"></script>
<script src="./mul-table.js" type="application/x-javascript"></script>
<script>
    var table = MultiSelectTable({
        onMultiSelect: function (start, end) {
            console.log(start);
            console.log(end);
        },
        onClickRow: function (data, i) {
            console.log(data);
        },
        textField: 'label'
        , el: $('#table')
    });

    table.render([
        {
            label: '1312313'
        }, {
            label: '1312313'
        }, {
            label: '1312313'
        }, {
            label: '1312313'
        }, {
            label: '1312313'
        }
    ]);
</script>
</html>

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM