zoukankan      html  css  js  c++  java
  • 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>

  • 相关阅读:
    setHapticFeedbackEnabled在androi的作用
    Android 跑马灯
    jQuery中绑定事件的命名空间详解
    可见即所得的CSS编辑设计
    盘点8种CSS实现垂直居中水平居中的绝对定位居中技术
    用到的知识点
    用PS去除图片中文字的6个方法
    html页面头部里的meta
    px pt em对应关系
    phpMyAdmin安装与配置(涉及LAMP配置)
  • 原文地址:https://www.cnblogs.com/chenss15060100790/p/13843312.html
Copyright © 2011-2022 走看看