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();
Автор: rafaylik