Скроллинг контента методом касания и перетаскивания на jQuery

от автора

Hello, jQuery, again!
Посвящено тем сенсорным сингл тач экранам, которые еще не канули в лету и поддерживают события mouseDown и иже с ними. Именно таким оказался информационный терминал, на котором нужно было демонстрировать контент сайта.
Задача данного плагина — скроллинг контента посредством касания одним пальцем на сингл тач сенсорном экране.
Используемые событияmouseDown/Move/Out.
По умолчанию эта цепочка событий выделяет содержимое в пределах касания.
Реализация — до боли знакомое overflow:hidden, обертывание содержимого элемента и перемещение контента внутри.
Нерешенные проблемы — иногда, на грани между пересечением нижнего края и пятикратным замедлением, контент сдвигается вверх на определенный интервал. Примечательно, что при обратном движении (в момент пересечения этой черты) контент возвращается на свое место (сдвигается вниз).
Надеюсь, для кого-нибудь эта статья окажется полезной и найдет своё применение.
Вэлком в комментарии, жду ваши мысли, ваш конструктив и негатив, всё, что направлено на улучшение данного кода!

Испытательный стенд на jsFiddle (48 строк некомментированного кода)

Начнем с разметки. У нас есть блок с контентом

<div id="content"> 	<h2>Touch and drag content</h2> 	<p>Lorem ipsum dolor sit amet...</p> </div> 

#content { 	position:absolute; 	left:50px; 	top:50px; 	width:500px; 	height:350px; 	text-align:justify; }

Далее — подробное комментирование каждого действия.

// оборачиваем плагин в анонимную функцию (function($){ // пишем функцию с именем нашего плагина $.fn.touchanddrag = function(){ 	// оборачиваем содержимое нашего элемента в дочерний элемент, который и будем перемещать 	// исходный же элемент сохраняет свою разметку и свойства, заданные ему в css 	this.wrapInner('<div>'); 	// исходный элемент теперь стал контейнером, а новый элемент - обертка для его данных 	// то есть исходный элемент (box) - родитель, а новый элемент (data) - дочерний 	var box = this, 		data = this.children(); 	// прячем полосу прокрутки 	box.css({'overflow':'hidden'}); 	// позиционируем элемент data 	data.css({'position':'absolute','cursor':'default'}); 	// событие касания на элементе 	data.mousedown(function(e){ 		// высота элементов для дальнейших вычислений 		var hgtBox = box.height(), 			hgtData = data.height(); 		// проверяем, достаточно ли контента для прокрутки 		if (hgtData>hgtBox) { 			// позиция касания 			var posTap = e.pageY, 				// позиция элемента data относительно элемента box 				posData = data.position().top, 				posShift, 				// событие скольжения в пределах документа 				mouseMove = function(e){ 					// расстояние, пройденное относительно первого касания 					posShift = e.pageY-posTap; 					// если прокрутили контент выше верхнего края 					if (data.position().top>0){ 						// перемещаем контент, но в 5 раз медленнее 						// фрагмент имитации кинетической прокрутки 						data.css({'top':(posData+posShift)/5}); 					// если прокрутили контент ниже нижнего края 					} else if ((data.position().top+hgtData)<hgtBox){ 						// замедляем перемещение в пять раз 						data.css({'top':(hgtBox-hgtData)+(posShift/5)}); 					// прокрутка контента в пределах видимости родителя 					} else { 						// добавляем разницу к предыдущим координатам 						data.css({'top':posData+posShift}); 					} 				}, 				// событие отпускания 				mouseUp = function(){ 					// отменяем мониторинг перетаскивания и блокировку выделения 					$(document).off('mousemove',mouseMove).off('mouseup',mouseUp); 					$(document).off('mousedown',selection); 					// возвращаем вид курсора 					data.css({'cursor':'default'}); 					// если после прокрутки контент оказался выше верхнего края						 					if (data.position().top>0){ 						// плавно возвращаем его в крайнюю верхнюю позицию 						// фрагмент имитации кинетической прокрутки 						data.animate({'top':0},250); 					// если после прокрутки контент оказался ниже нижнего края 					} else if ((data.position().top+hgtData)<hgtBox) { 						// плавно возвращаем его в крайнюю нижнюю позицию 						data.animate({'top':hgtBox-hgtData},250); 					} 				}, 				// снятие выделения при перетаскивании контента 				selection = function(){ 					if (window.getSelection){window.getSelection().removeAllRanges()} 					else {document.selection.empty()} 					return false; 				}; 			// меняем вид курсора на время перетаскивания 			data.css({'cursor':'move'}); 			// инициализируем мониторинг перетаскивания и блокировку выделения 			$(document).on('mousedown',selection).on('mousemove',mouseMove); 			$(document).on('mouseup',mouseUp).on('contextmenu',mouseUp); 			$(window).on('blur',mouseUp); 		} 	}); 	return this; }; })(jQuery);

Вызываем плагин

$('#content').touchanddrag();

ссылка на оригинал статьи https://habrahabr.ru/post/313922/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *