Lo que proponemos a continuación es casi un nimiedad, se trata de una función en javascript que te ayuda a mover un elemento con el cursor o el touch. Te ahorrará tiempo y hará sencilla la lógica para el caso.
La idea es pasarle a la función el elemento a mover, y las funciones que se ejecutarán al comienzo, mientras se mueve y al final del evento. La misma se encargará del resto. Sin más, este es el código.
function JsMove(el, startFn, moveFn, endFn) {
function setClient(event) {
var e = event;
switch (event.type) {
case 'touchstart': e = event.touches[0]; break;
case 'touchmove':
case 'touchend': e = event.changedTouches[0]; break;
}
if (e.clientX || e.clientY) {
if (e !== event) {
event.clientX = e.clientX;
event.clientY = e.clientY;
}
} else if (e.pageX || e.pageY) {
event.clientX = e.pageX - document.body.scrollLeft - document.documentElement.scrollLeft;
event.clientY = e.pageY - document.body.scrollTop - document.documentElement.scrollTop;
}
};
function setEvent(el, name, fn, status) {
name.split(' ').forEach(function(n) { el[(status ? 'add' : 'remove') + 'EventListener'](n, fn); });
};
function activate(status) {
setEvent(document, 'mousemove touchmove', _moveFn, status);
setEvent(document, 'mouseup touchend', _endFn, status);
};
function _startFn(event) {
setClient(event);
startFn(event);
activate(true);
};
function _moveFn(event) {
setClient(event);
moveFn(event);
};
function _endFn(event) {
if (typeof endFn == 'function') {
setClient(event);
endFn(event);
}
activate(false);
};
setEvent(el, 'mousedown touchstart', _startFn, true);
}
Si es necesario, la función creará las propiedades de clientX y clientY, para que siempre estén a disposición.
Por último, en el artículo Mover un rectángulo dentro de otro veremos un ejemplo de uso.