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