Arrastre Genérico

Autor Original:Mike Hall URL ORIGINAL : http://www.brainjar.com/dhtml/drag/ TÍTULO ORIGINAL : Generic Drag Traducción al castellano:Pedro Palazón Candel URL CASTELLANO : http://kusor.net/traducciones/brainjar.es/drag1.es.html

Arrastre ('Drag') Genérico

Ver la página demo para la versión final del código.

El Proceso de Arrastre

El proceso básico de arrastre consta de tres etapas: Inicialización del arrastre cuando el botón del mouse es presionado por primera vez, moviendo el elemento blanco ('target') cuando el mouse se ha movido y, finalmente, deteniendo el arrastre cuando el botón del mouse se suelta.

Inicializando el Arrastre

La función dragStart() es llamada por el manejador del evento onmousedown de algún elemento, tal como se ha descrito anteriormente. Dicha función determina primero el elemento 'target' para el arrastre.

function dragStart(event, id) {

var el;
var x, y;

// If an element id was given, find it. Otherwise use the element being
// clicked on.

if (id)
dragObj.elNode = document.getElementById(id);
else {
if (browser.isIE)
dragObj.elNode = window.event.srcElement;
if (browser.isNS)
dragObj.elNode = event.target;

// If this is a text node, use its parent element.

if (dragObj.elNode.nodeType == 3)
dragObj.elNode = dragObj.elNode.parentNode;
}

Si se le pasa un id , el script utiliza document.getElementById() para localizar el  elemento. De cualquier otro modo utiliza el objeto event para determinar sobre qué elemento está el mouse y lo utiliza por defecto. En cualquier caso, el elemento 'target' es asignado a dragObj.elNode.

Ver Introduction to the Document Object Model para los detalles sobre los tipos de nodos.

Una situación especial debe ser revisada. Si el mouse está sobre texto, el blanco ('target') del evento mousedown será un nodo de texto, en lugar de un nodo elemento. Los nodos de texto contienen justamente eso, datos textuales, y no tienen propiedades de estilo, como posición. En su lugar, la apariencia y posición del texto está determinada por las propiedades de estilo del elemento al que pertenezcan.

Por tanto, si sucede que el nodeType del blanco ('target') del evento es un nodo de texto TEXT_NODE (= 3), el script toma su parentNode en su lugar. El padre de un nodo de texto es siempre el elemento que contiene dicho texto.

Compatibilidad de Navegadores

Netscape define constantes en el DOM para cada tipo de nodo. Por ejemplo, document.ELEMENT_NODE devolvería un valor de 1. Internet Explorer no nos las proporciona, por lo que el valor numérico actual es utilizada en su lugar en el script.

El siguiente paso es encontrar la posición actual del puntero del mouse. Estas coordenadas iniciales en pixels serán utilizadas después para compararlas con la posición del mouse durante el arrastre.

  // Get cursor position with respect to the page.

if (browser.isIE) {
x = window.event.clientX + document.documentElement.scrollLeft
+ document.body.scrollLeft;
y = window.event.clientY + document.documentElement.scrollTop
+ document.body.scrollTop;
}
if (browser.isNS) {
x = event.clientX + window.scrollX;
y = event.clientY + window.scrollY;
}

Nótese que los valores del objeto evento clientX y clientY son relativos al área de visión ('viewport') de la ventana del navegador, no a la página. Podría darse el caso en que se hubiese hecho scroll sobre la ventana durante el arrastre, y quisiésemos obtener la posición del cursor relativa a la página en si misma. Por lo tanto, le agregaremos los valores actuales de 'scroll offsets'.

Puedes ver la diferencia por tí mismo haciendo scroll en esta página y click en cualquier parte de ella. Los valores clientX y clientY se muestran en la barra de estado de la ventana del navegador acompañados por los valores calculados de 'page offset'.

Compatibilidad de Navegadores

Internet Explorer tiene propiedades de scroll offset properties tanto para el objeto document.body como para el objeto document.documentElement . Pero IE 5 sólo actualiza el par en document.body mientras que el par en document.documentElement siempre devuelve cero. IE 6 hace justamente lo contrario.

El código siguiente  añade los valores de scroll offset para ambos objetos, por lo que devolverá los valores correctos independientemente de la versión.

Netscape almacena los valores de scroll offset de la página como propiedades del objeto window.

A continuación, la función encuentra la posición del elemento blanco ('target'), usando la parte numérica de sus valores de estilo left y top. Estos valores se guardan en dragObj acompañados por las coordenadas del mouse.

  // Save starting positions of cursor and element.

dragObj.cursorStartX = x;
dragObj.cursorStartY = y;
dragObj.elStartLeft = parseInt(dragObj.elNode.style.left, 10);
dragObj.elStartTop = parseInt(dragObj.elNode.style.top, 10);

if (isNaN(dragObj.elStartLeft)) dragObj.elStartLeft = 0;
if (isNaN(dragObj.elStartTop)) dragObj.elStartTop = 0;

Nótese aquí que si left o top no se han fijado usando estilos 'inline' en el elemento, el código asumes que su valor es cero.

Para llevar al elemento a la parte más alta del orden de apilamiento, el script actualiza su propiedad de estilo zIndex, después de haber aumentado el valor de dragObj.zIndex.

  // Update element's z-index.

dragObj.elNode.style.zIndex = ++dragObj.zIndex;

El último paso es configurar la captura de los eventos mousemove y mouseup en toda la página, asignándoles los manejadores dragGo() y dragStop() respectivamente.

  // Capture mousemove and mouseup events on the page.

if (browser.isIE) {
document.attachEvent("onmousemove", dragGo);
document.attachEvent("onmouseup", dragStop);
window.event.cancelBubble = true;
window.event.returnValue = false;
}
if (browser.isNS) {
document.addEventListener("mousemove", dragGo, true);
document.addEventListener("mouseup", dragStop, true);
event.preventDefault();
}

El script cancela entonces el burbujeo de eventos actual y cualquier acción por defecto. Normalmente, si arrastras el mouse sobre una página el navegador resaltará una sección de texto o cualquier otro contenido. Deteniendo el evento como hemos hecho prevendremos dicha acción durante el arrastre.

Previo | Siguiente

BrainJar.com · ©1999-2002 by Mike Hall 
Publicado con autorización explícita del autor.
Puedes encontrar más artículos y tutoriales relacionados con dhtml en esta web.