javascript - shift多选事件
业务需求:一般的多选,我们会给用户很多的 checkbox,让用户挨个点击,我们可以做一个优化,像 PC 一样,按住 shift 可以多选。
shift多选事件
直接调用原生的 onkeydown、onkeyup,如果代码组织得不好,会导致代码混乱,这里进行一个简单的封装。
想要进一步封装组件,需要有一定的计算能力,维护成本较高,但是相对的,能获取不错的用户体验。
注意:侦听的是 document 的事件,这是个全局的事件,事件不用之后,需要进行解绑,避免产生冲突。
/**
* 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;
}
}
}
样例
jquery环境下,封装一个可以多选的表格。
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 () {
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>
疯狂的妞妞 :每一天,做什么都好,不要什么都不做!