一般的多选,我们会给用户很多的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>