创建一个 JavaScript 对象
我会说我对 javascript 和 jQuery 相当了解,嗯,足以完成工作,而且做得很好。 但是我对 js 缺乏深入的理解。
我已经创建了一些用于突出显示表格元素的函数。 ctrl+单击切换选择 shift+单击+拖动突出显示选择
我的问题与我的实现是否是最好的方式无关,但...
我如何抽象此功能,以便我可以将其添加到任何表格中。比如,如果我添加更多突出显示功能等,并将其放在自己的 .js 文件中。我如何将其附加到任何 html 表格?
抱歉,如果这个问题已经得到解答,但我想不出要搜索什么。
谢谢。
****最新代码**** 此代码位于其自己的 .js 文件中,并附加到我的表格中。 所有当前功能都在那里。我唯一担心的是 .off() 函数。就我而言,我正在重新加载新表....当我输入此内容时,我意识到我应该清空表中的 tr,而不是一直重新创建一个新表,然后我就可以摆脱 .off() 调用。
$.fn.addEvents = function(obj)
{
console.log("Adding events to table");
var properties = $.extend(true,
{
shifting: false,
ctrling: false,
mousing: false,
mouseenter: 0,
mouseleave: 0,
mousestartindex: 0,
mouseenterindex: 0,
mouseleaveindex: 0,
trajectory: null,
tmptrajectory: null
}, obj || {});
$(document)
.off('mouseup')
.on('mouseup', function(e)
{
properties.mousing = false;
properties.trajectory = null;
})
.off("keyup")
.on("keyup", function(e)
{
if(e.which == 16)
{
properties.shifting = false;
}
if(e.which == 17)
{
properties.ctrling = false;
}
})
.off("keydown")
.on("keydown", function(e)
{
if(e.which == 16)
{
properties.shifting = true;
}
if(e.which == 17)
{
properties.ctrling = true;
}
if($(this).find('tr.selected').length > 0)
{
switch(e.which)
{
//case 37: // left
//break;
case 38: // up
var index = $(this).find('tr.selected').index();
if(index > 0)
{
$(this).find('tr').removeClass('selected');
$(this).find('tr td').removeClass('selected');
$(this).find('tr:eq(' + index + ')').addClass('selected');
$(this).find('tr:eq(' + index + ') td').addClass('selected');
}
break;
//case 39: // right
//break;
case 40: // down
var index = $(this).find('tr.selected').index();
if(index < $(this).find('tr').length - 2)
{
$(this).find('tr').removeClass('selected');
$(this).find('tr td').removeClass('selected');
$(this).find('tr:eq(' + (index+2) + ')').addClass('selected');
$(this).find('tr:eq(' + (index+2) + ') td').addClass('selected');
}
break;
case 117: // f6
var index = $(this).find('tr.selected').index();
if(index > 0)
{
....
}
break;
case 118: // f7
var index = $(this).find('tr.selected').index();
if(index < $(this).find('tr').length - 1)
{
....
}
break;
default: return; // exit this handler for other keys
}
e.preventDefault(); // prevent the default action (scroll / move caret)
}
return;
});
return $(this)
.off('click')
.off('contextmenu')
.on('click', function()
{
if(!properties.ctrling && !properties.shifting)
{
$('#datatablebody tr, #datatablebody tr td').removeClass('selected');
$(this).addClass('selected');
$(this).find('td').addClass('selected');
}
else if(properties.ctrling && $(this).hasClass('selected'))
{
$(this).removeClass('selected');
$(this).find('td').removeClass('selected');
}
else if(properties.ctrling && !$(this).hasClass('selected'))
{
$(this).addClass('selected');
$(this).find('td').addClass('selected');
}
})
.on('contextmenu', function(ev)
{
ev.preventDefault();
$('#datatablebody tr, #datatablebody tr td').removeClass('selected');
$(this).addClass('selected');
$(this).find('td').addClass('selected');
showContextMenuTR($(this).closest('tr').attr('id'), ev.clientX, ev.clientY);
return false;
})
.off('mousedown')
.on('mousedown', function(e)
{
properties.mousing = true;
properties.mousestartindex = $(this).index();
if(properties.shifting && properties.mousing)
{
multiselectrow($(this));
}
})
.off('mouseenter')
.on('mouseenter', function(e)
{
properties.mouseenter = e.clientY;
properties.mouseenterindex = $(this).index();
if(properties.tmptrajectory === properties.trajectory)
{
if(properties.shifting && properties.mousing)
{
multiselectrow($(this));
}
}
})
.off('mouseleave')
.on('mouseleave', function(e)
{
properties.mouseleave = e.clientY;
if(properties.shifting && properties.mousing)
{
properties.tmptrajectory = properties.mouseenter - properties.mouseleave < 0?1:-1;
}
if(properties.trajectory != null && properties.tmptrajectory !== properties.trajectory && $(this).index() !== properties.mousestartindex)
{
if(properties.shifting && properties.mousing)
{
multiselectrow($(this));
}
}
if(properties.shifting && properties.mousing)
{
if(properties.trajectory == null)
{
properties.trajectory = properties.tmptrajectory;
}
else if(properties.tmptrajectory !== properties.trajectory && $(this).index() === properties.mousestartindex)
{
properties.trajectory = properties.tmptrajectory;
}
}
})
.off('mouseup')
.on('mouseup', function(e)
{
properties.mousing = false;
properties.trajectory = null;
if(properties.shifting && properties.mousing)
{
multiselectrow($(this));
}
});
}
function multiselectrow(obj)
{
if($(obj).hasClass('selected'))
{
$(obj).removeClass('selected');
$(obj).find('td').removeClass('selected');
}
else
{
$(obj).addClass('selected');
$(obj).find('td').addClass('selected');
}
}
您可以将所有这些包装在一个函数中,因为您有一些与单独选择相关的局部变量
$.fn.addEvents = function(obj) {
var properties = $.extend(true, {
shifting: false,
ctrling: false,
mousing: false,
mouseenter: 0,
mouseleave: 0,
trajectory: null
}, obj || {});
return $(this)
.off('click')
.off('contextmenu')
.on('click', function() {
.....
})
.on('mouseleave', function(e) {
//rename your local variables with `properties.` prefix
properties.mouseleave = e.clientY;
if (properties.shifting && properties.mousing) {
tmptrajectory = properties.mouseenter - properties.mouseleave < 0 ? 1 : -1;
}
if ($(this).hasClass('selected') && properties.shifting && properties.mousing && properties.trajectory != null && properties.trajectory != tmptrajectory) {
$(this).removeClass('selected');
$(this).find('td').removeClass('selected');
}
....
});
}
用法
$('#datatablebody tr').addEvents({ shifting: false, ctrling: true }); //custom settings
$('#someother tr').addEvents(); //default settings
您可以将该功能添加到一个类中,然后将该类添加到您想要影响的表中...
在这里我创建了类
.myTableBeh
,并且具有该类的所有表都将具有您编程的行为。
var shifting = false;
var ctrling = false;
var mousing = false;
var mouseenter = 0;
var mouseleave = 0;
var trajectory = null;
$('.myTableBeh tr')
.off('click')
.off('contextmenu')
.on('click', function()
{
if(!ctrling)
{
$('.myTableBeh tr, .myTableBeh tr td').removeClass('selected');
$(this).addClass('selected');
$(this).find('td').addClass('selected');
}
else if(ctrling && $(this).hasClass('selected'))
{
$(this).removeClass('selected');
$(this).find('td').removeClass('selected');
}
else if(ctrling && !$(this).hasClass('selected'))
{
$(this).addClass('selected');
$(this).find('td').addClass('selected');
}
})
.on('contextmenu', function(ev)
{
ev.preventDefault();
$('.myTableBeh tr, .myTableBeh tr td').removeClass('selected');
$(this).addClass('selected');
$(this).find('td').addClass('selected');
showContextMenuTR($(this).closest('tr').attr('id'), ev.clientX, ev.clientY);
return false;
})
.off('mousedown')
.on('mousedown', function(e)
{
mousing = true;
multiselectrow($(this));
})
.off('mouseenter')
.on('mouseenter', function(e)
{
mouseenter = e.clientY;
multiselectrow($(this));
})
.off('mouseleave')
.on('mouseleave', function(e)
{
mouseleave = e.clientY;
if(shifting && mousing)
{
tmptrajectory = mouseenter - mouseleave < 0?1:-1;
}
if($(this).hasClass('selected') && shifting && mousing && trajectory != null && trajectory != tmptrajectory)
{
$(this).removeClass('selected');
$(this).find('td').removeClass('selected');
}
if(shifting && mousing && trajectory == null)
{
trajectory = tmptrajectory;
}
})
.off('mouseup')
.on('mouseup', function(e)
{
mousing = false;
trajectory = null;
multiselectrow($(this));
});
感谢@JAG的回答,我能够为任何处理突出显示的HTML表格创建一个不错的附加组件。
查看工作版本的fiddle,如果您发现它对您的网站有帮助或有用,请使用它。
您甚至可以实现键来在表格中上下移动tr的位置。我删除了我的实现,因为它特定于我正在从事的项目。
我这样做是为了让您必须将鼠标悬停在表格上才能与其交互,将鼠标移开以取消焦点。
https://jsfiddle.net/kwj74kg0/2/
//Add the events simply by running this
$('#dtable tr').addEvents(0);
/**
* This add on can be applied and customized to any html tr set i.e. $('#tableid tr').addEvents()
* It will add highlighting capability to the table.
*
* Single click highlight tr
* Click -> Shift + click highlight/toggle range
* Shift+MouseDown+Drag highlight/toggle range
* Ctrl+Click toggle item
*
*
* @author Michaela Ervin
*
* @param tabindex
*
* Help from JAG on http://stackoverflow.com/questions/39022116/create-a-javascript-object
*/
$.fn.addEvents = function(tabindex)
{
console.log("Adding events to table");
var properties = $.extend(true,
{
shifting: false,
ctrling: false,
mousing: false,
mouseenter: 0,
mouseleave: 0,
mousestartindex: 0,
mouseenterindex: null,
mouseleaveindex: null,
trajectory: null,
tmptrajectory: null
}, {});
/**
* Add events to closest table.
*/
$(this)
.closest('table')
.attr('tabindex', tabindex)
.off('mouseenter')
.on('mouseenter', function()
{
$(this).focus();
})
.off('mouseleave')
.on('mouseleave', function()
{
$(this).blur();
properties.mousing = false;
properties.trajectory = null;
properties.mouseenterindex = null;
properties.mouseleaveindex = null;
properties.mouseintermediateindex = null;
})
.off("keyup")
.on("keyup", function(e)
{
if(e.which == 16)
{
properties.shifting = false;
}
if(e.which == 17)
{
properties.ctrling = false;
}
})
.off("keydown")
.on("keydown", function(e)
{
if(e.which == 16)
{
properties.shifting = true;
}
if(e.which == 17)
{
properties.ctrling = true;
}
if($(this).find('tr.selected').length > 0)
{
switch(e.which)
{
//case 37: // left
//break;
case 38: // up
var index = $(this).find('tr.selected').index();
if(index > 0)
{
$(this).find('tr').removeClass('selected');
$(this).find('tr td').removeClass('selected');
$(this).find('tr:eq(' + index + ')').addClass('selected');
$(this).find('tr:eq(' + index + ') td').addClass('selected');
}
break;
//case 39: // right
//break;
case 40: // down
var index = $(this).find('tr.selected').index();
if(index < $(this).find('tr').length - 2)
{
$(this).find('tr').removeClass('selected');
$(this).find('tr td').removeClass('selected');
$(this).find('tr:eq(' + (index+2) + ')').addClass('selected');
$(this).find('tr:eq(' + (index+2) + ') td').addClass('selected');
}
break;
case 117: // f6
var index = $(this).find('tr.selected').index();
if(index > 0)
{
//Function to move tr 'up'.
}
break;
case 118: // f7
var index = $(this).find('tr.selected').index();
if(index < $(this).find('tr').length - 1)
{
//Function to move tr 'down'.
}
break;
default: return; // exit this handler for other keys
}
e.preventDefault(); // prevent the default action (scroll / move caret)
}
return;
});
/**
* Add tr specific events
*/
return $(this)
.off('click')
.on('click', function()
{
if(!properties.shifting && properties.mouseenterindex != null)
{
properties.mouseenterindex = null;
properties.mousing = false;
}
if(!properties.ctrling && !properties.shifting && properties.mouseenterindex == null)
{
$(this).parent().find('tr').removeClass('selected');
$(this).parent().find('tr td').removeClass('selected');
$(this).addClass('selected');
$(this).find('td').addClass('selected');
}
else if(properties.ctrling && $(this).hasClass('selected'))
{
$(this).removeClass('selected');
$(this).find('td').removeClass('selected');
}
else if(properties.ctrling && !$(this).hasClass('selected'))
{
$(this).addClass('selected');
$(this).find('td').addClass('selected');
}
if(properties.mouseenterindex == null)
{
properties.mouseenterindex = $(this).index();
}
else if(properties.shifting && properties.mouseenterindex != null)
{
properties.mouseleaveindex = $(this).index();
highlightRange($(this).parent(), properties.mouseenterindex, properties.mouseleaveindex, properties.mouseenterindex);
properties.mouseenterindex = null;
properties.mouseleaveindex = null;
}
})
.off('contextmenu')
.on('contextmenu', function(ev)
{
ev.preventDefault();
$(this).parent().find('tr').removeClass('selected');
$(this).parent().find('tr td').removeClass('selected');
$(this).addClass('selected');
$(this).find('td').addClass('selected');
//Put your context menu here
return false;
})
.off('mousedown')
.on('mousedown', function(e)
{
properties.mousing = true;
properties.mousestartindex = $(this).index();
if(properties.shifting && properties.mousing && properties.mouseenterindex == null)
{
multiselectrow($(this));
}
})
.off('mouseenter')
.on('mouseenter', function(e)
{
properties.mouseenter = e.clientY;
if(properties.tmptrajectory === properties.trajectory)
{
if(properties.shifting && properties.mousing)
{
multiselectrow($(this));
}
}
})
.off('mouseleave')
.on('mouseleave', function(e)
{
properties.mouseleave = e.clientY;
if(properties.shifting && properties.mousing)
{
properties.tmptrajectory = properties.mouseenter - properties.mouseleave < 0?1:-1;
}
if(properties.trajectory != null && properties.tmptrajectory !== properties.trajectory && $(this).index() !== properties.mousestartindex)
{
if(properties.shifting && properties.mousing)
{
multiselectrow($(this));
}
}
if(properties.shifting && properties.mousing)
{
if(properties.trajectory == null)
{
properties.trajectory = properties.tmptrajectory;
}
else if(properties.tmptrajectory !== properties.trajectory && $(this).index() === properties.mousestartindex)
{
properties.trajectory = properties.tmptrajectory;
}
}
})
.off('mouseup')
.on('mouseup', function(e)
{
properties.mousing = false;
properties.trajectory = null;
if(!properties.shifting)
{
properties.mouseenterindex = null;
properties.mouseleaveindex = null;
}
});
}
function multiselectrow(obj)
{
if($(obj).hasClass('selected'))
{
$(obj).removeClass('selected');
$(obj).find('td').removeClass('selected');
}
else
{
$(obj).addClass('selected');
$(obj).find('td').addClass('selected');
}
}
function highlightRange(obj, start, end, mouseenterindex)
{
if(start < end)
{
for(var i=start; i<=end; i+=1)
{
if(i !== mouseenterindex)
{
multiselectrow($(obj).find('tr').eq(i));
}
}
}
else
{
for(var i=start; i>=end; i-=1)
{
if(i !== mouseenterindex)
{
multiselectrow($(obj).find('tr').eq(i));
}
}
}
}