2008-10-22 16 views
14

Implementé un conjunto de elementos arrastrables que se pueden soltar en algunos contenedores usando jQuery. Lo que necesito es una animación que mueva un elemento a un contenedor específico sin interacción del usuario. El problema es que los elementos y los contenedores de caída se encuentran por completo en diferentes partes del DOM y se posicionan principalmente con flotador.Obtener la posición relativa entre 2 elementos DOM usando JavaScript

Todo lo que necesito es un código para obtener la diferencia de posición absoluta entre 2 elementos DOM flotantes, preferiblemente usando jQuery. Lo único que encontré fueron algunos hacks analizando el DOM, pero siempre muy específicos del navegador (por ejemplo, "esto no funciona bien con Firefox o IE o lo que sea").

Mejor sería algo como esto:

var distance = getDistance(element1, element2); 

o en notación jQuery:

var distance = $(element1).distanceTo($(element2)); 

Respuesta

22

nunca he usado jQuery, de echar una ojeada a la API, por lo que puede suponer que puede hacer lo siguiente:

 
var o1 = $(element1).offset(); 
var o2 = $(element2).offset(); 
var dx = o1.left - o2.left; 
var dy = o1.top - o2.top; 
var distance = Math.sqrt(dx * dx + dy * dy); 
+0

Esto no funcionará porque .offset() solo devuelve la posición relativa al elemento principal. Como los elementos principales no son los mismos, los valores no se pueden usar. La parte de distancia diagonal no es importante por cierto, esperaba valores superiores e inferiores ;-) – davil

+0

Bueno, no estoy de acuerdo con usted. De acuerdo con la referencia jQuery (http://docs.jquery.com/CSS), el desplazamiento obtiene "el desplazamiento actual del primer elemento coincidente relativo a la ventana gráfica". viewport es la palabra clave, no es el offsetParent –

+0

El ejemplo en la página de compensación es bastante engañoso. Los ejemplos se cargan en iframes, lo que hace que parezca que la posición es solo relativa al padre, mientras que en realidad es relativa al documento (en este caso, el iframe) – nickf

1

Usando javascript puro.

var dx = obj1.offsetLeft - obj2.offsetLeft; 
var dy = obj1.offsetTop - obj2.offsetTop; 
var distance = Math.sqrt(Math.pow(dx,2) + Math.pow(dy,2)); 
+0

Igual aquí que con la respuesta de Sergey ... offsetLeft y offsetTop solo funcionan dentro del mismo elemento principal. – davil

1

¿Qué hay de lo siguiente?

var isIE = navigator.appName.indexOf("Microsoft") != -1; 

function getDistance(obj1, obj2){ 
    var obj1 = document.getElementById(obj1); 
    var obj2 = document.getElementById(obj2); 
    var pos1 = getRelativePos(obj1); 
    var pos2 = getRelativePos(obj2); 
    var dx = pos1.offsetLeft - pos2.offsetLeft; 
    var dy = pos1.offsetTop - pos2.offsetTop; 
    return {x:dx, y:dy}; 
} 
function getRelativePos(obj){ 
var pos = {offsetLeft:0,offsetTop:0}; 
while(obj!=null){ 
    pos.offsetLeft += obj.offsetLeft; 
    pos.offsetTop += obj.offsetTop; 
    obj = isIE ? obj.parentElement : obj.offsetParent; 
} 
return pos; 
} 
// 
var obj = getDistance("element1","element2") 
alert(obj.x+" | "+obj.y); 
+0

Esa prueba 'isIE' no es necesaria. ¿Por qué no solo 'obj = obj.offsetParent || obj.parentElement' (o lo que sea necesario). – alex

Cuestiones relacionadas