Показать сообщение отдельно
  #1 (permalink)  
Старый 05.01.2014, 03:42
Аватар для Zuenf
Кандидат Javascript-наук
Отправить личное сообщение для Zuenf Посмотреть профиль Найти все сообщения от Zuenf
 
Регистрация: 27.01.2012
Сообщений: 134

Класс выделения элементов. Нужна критика.
Учусь на практике.
Класс получает все выделяемые 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;
	}
}

Последний раз редактировалось Zuenf, 05.01.2014 в 13:50.
Ответить с цитированием