Учусь на практике.
Класс получает все выделяемые html-элементы(с классом selectClass) между координатами mousedown и mouseup. Существует возможность нажатия ctrl и соответственно добавления элементов в уже существующее выделение.
Хочется узнать, что сделано криво, что не красиво, а что вообще не правильно.
Если есть какие-то функции, существующие, чтобы облегчить какие-либо ситуации в моем примере, буду рад узнать о них.
//Класс Select
function Select( selectBox, selectClass, visualSelectionClass){
var selectBox = selectBox || document; //Контейнер в котором возможно выделение
var selectClass = selectClass || '.selectable'; //Клас элемента который можно выделить
var visualSelectionClass = visualSelectionClass || '.selection'; //Класс для блока визуального выделения
var coord = {}; //Координаты выделенной области
var ctrl = false; //Состояние клавиши CTRL
var selectedElements = []; //Выделенные элементы
//Координаты мыши относительно элемента
function mouseCoordRelativeElement(event, elem){
return {'X':event.pageX - $(elem).offset().left, 'Y':event.pageY - $(elem).offset().top};
}
//----------------------Нажатие CTRL------------------------
function isCtrl(e){
if( e.keyCode == 17 ){
ctrl = true;
$(document).unbind( 'keydown', isCtrl );
$(document).bind( 'keyup', offCtrl );
}
}
function offCtrl(e){
if( e.keyCode == 17 ){
ctrl = false;
$(document).bind( 'keydown', isCtrl );
$(document).unbind( 'keyup', offCtrl );
}
}
//----------------------------------------------------------
//--------------Выделение и добавление в массив-------------
function startSelect(e){
var t = e.target
var c = mouseCoordRelativeElement(e, selectBox);
//Клик был не на элементе(на пустом пространстве) -> начинаем выделение;
if ( !$(t).hasClass( selectClass.substring(1) ) ){
coord.x1 = c.X;
coord.y1 = c.Y;
//Начало показа визуального выделения;
startVisualSelection();
}else{//Клик был на элементе;
//Если он не входит в массив выбранных элементов
if(selectedElements.indexOf(t) == -1){
if ( !ctrl ) selectedElements = [];
//Запиcываем его в массив выделенных элементов;
selectedElements.push(t);
}
}
return false;
}
function endSelect(e){
if(coord.x1 === undefined) return;
var c = mouseCoordRelativeElement(e, selectBox);
coord.x2 = c.X;
coord.y2 = c.Y;
//По идее координаты начала выделения < координат конца
//Cоответственно если координаты mouseup < координаты начала выделения(mousedown), то координаты начала должны стать координатами конца
if( c.X < coord.x1 ){
coord.x2 = coord.x1;
coord.x1 = c.X;
}
if( c.Y < coord.y1 ){
coord.y2 = coord.y1;
coord.y1 = c.Y;
}
//Проверка вхождения выделяемых элементов в область выделения и запись их в массив выделенных элементов
selectElements();
//Остановка визуального выделения;
stopVisualSelection();
coord = {};
}
function selectElements(){
if( !ctrl ) selectedElements = [];
//Идем по всем выделяемым элементам
$(selectClass).each(function(){
var y = $(this).position().top + $(this).outerHeight()/2;
var x = $(this).position().left + $(this).outerWidth()/2;
//Если центральная точка элемента находится внутри выделения и его еще нет в масииве то...
if( x>coord.x1 && y>coord.y1 && x<coord.x2 && y<coord.y2 && selectedElements.indexOf(this) == -1 ){
//...добавляем в массив
selectedElements.push(this);
}
});
}
//---------------------------------------------------
//----------------Визуальная часть-------------------
function initVisualSelection(){
$(selectBox).append('<div class="'+visualSelectionClass.substring(1)+'"></div>');
$(visualSelectionClass).css({'position':'absolute', 'display':'none'});
}
function startVisualSelection(){
$(visualSelectionClass).css({'display':'block', 'top':coord.y1, 'left':coord.x1});
$(selectBox).bind( 'mousemove', viewVisualSelection );
}
function viewVisualSelection(e){
var c = mouseCoordRelativeElement(e, selectBox);
var height = c.Y - coord.y1;
var width = c.X - coord.x1;
var top = coord.y1;
var left = coord.x1;
if( height < 0 ){
top = c.Y;
height *= -1;
}
if( width < 0 ){
left = c.X;
width *= -1;
}
$(visualSelectionClass).css({'top':top, 'left':left,'height':height, 'width':width});
}
function stopVisualSelection(){
$(visualSelectionClass).css({'display':'none','height':'0', 'width':'0'});
$(selectBox).unbind( 'mousemove', viewVisualSelection );
}
//------------------------------------------
this.init = function(){
$(document).bind( 'keydown', isCtrl );
$(selectBox).bind( 'mousedown', startSelect );
$(selectBox).bind( 'mouseup', endSelect );
//Инициализация визуального выделения;
initVisualSelection();
}
//Возвращает массив выбраных елементов;
this.getSelectedElements = function(){
return selectedElements;
}
}