..."Ahora entiendo lo que querés hacer. :) Es medio complicadito!"...
Lo que me sorprende es que no debería serlo. Me resisto a creer que entre todas las APIs no exista algo que me permita obtener las coordenadas del area cliente de un elemento. Lo de clientLeft y clientTop fue lo primero que intenté, y muy rápidamente me desilusioné cuando descubrí que no fueron implementadas en Firefox, aún cuando este si implementa clientWidth y clientHeight. De hecho, buceando un poco en el site de Mozilla, me cruzé con comentarios de que 'habría' intenciones de implementarlas. Con respecto a getComputedStyle(), esto es lo que estoy usando para copiar el estilo del elemento destino. Pero tu sugerencia me sirvió porque cuando me encontraba redactando una respuesta explicando que el problema de getComputedStyle() se presentaba en el caso de que el borde haya sido definido en una unidad diferente a pixels, por ejemplo como 'thick', quize confirmar esto en el ejemplo, y me sorprendí cuando getComputedStyle() me devolvió el ancho del borde correctamente convertido a pixels. Estaba convencido de que siempre devolvía el valor en las unidades en las que fue especificado, ya que en algún momento de las doce millones de pruebas que hice estaba seguro de haber visto esto. Pero ahora creo que me debo de haber confundido con currentStyle, que es el método equivalente en IE, y que si devuelve valores expresados en las unidades originales. Creo que esto fue lo que me llevó a descartar la opción de obtener las coordenadas a partir del border externo y sumando el ancho del borde en pixels. Pero en apariencia una combinación de clientLeft / clientTop para IE, y getComputedStyle() para Firefox podría funcionar. Parece que tenía todas las piezas del rompecabezas, pero no supe armarlo. Gracias Luis. Claro que todavía no probé nada en Opera y Safari... Además, cuanto más me me meto en el tema, más complicado se vuelve. En las pruebas triviales todo funciona de maravillas. Pero el mismo código en páginas complejas, donde hay una variedad de estilos, elementos anidados, con posiciones absolutas y relativas, las cosas no son tan simples. En fin... Me quedé un poco intrigado por la siguiente frase ..."También elaborándolo un poco más, podrías usar getComputedStyle en todos los casos (incluído IE)."... Te importaría explayarte un poco más con respecto a este punto. IE6 no soporta getComputedStyle, no estoy seguro sobre IE7 pero una prueba rápida parece sugerir que tampoco. A propósito, tenés idea si existe alguna forma de obtener el estilo de un pseudo-elemento, por ejemplo 'first-letter', en el caso de IE. El problema se presenta cuando intento copiar el estilo del elemento destino cuando este contiene pseudo-elementos. En el caso de getComputedStyle('elemento', 'pseudo-elemento'), el segundo parámetro permite acceder a ellos, pero en el caso de IE no parece existir forma de hacer referencia a estos a través de currentStyle. Muchas gracias nuevamente. Saludos, Fernando Tubio ----- Original Message ----- From: Luis Farzati To: puntonet@mug.org.ar Sent: Saturday, December 16, 2006 10:25 AM Subject: [puntonet] OFF-TOPIC - Recuperar la posicion de un elemento HTML Hola Fernando, Ahora entiendo lo que querés hacer. :) Es medio complicadito! En IE tenés la propiedad clientLeft y clientTop, que te devuelve precisamente el ancho del borde izquierdo y superior respectivamente, aunque esto no es W3C compliant y en otros browsers como el Firefox no está disponible. Ahora, intrigado me puse a investigar alguna solución y encontré una opción que habría que ver si te sirve: Podrías recuperar el ancho del borde de otra forma que es utilizando el método DOM getComputedStyle. Esto, como el nombre lo dice, te devuelve los valores computados del estilo de un elemento (en vez de traerte los valores literales que obtenés con la propiedad style). Con lo cual podrías ir por la primer opción, si evaluás que el browser tiene el soporte ala IE, y en caso contrario utilizar getComputedStyle. Un ejemplo rápido: if(dst.currentStyle && dst.currentStyle.hasLayout ) { src.style.top = dst.offsetTop + dst.offsetParent.offsetTop + dst.clientTop + 'px'; src.style.left = dst.offsetLeft + dst.offsetParent.offsetLeft + dst.clientLeft + 'px'; } else { var realTop = parseInt( document.defaultView.getComputedStyle(dst, "").getPropertyValue('border-top-width').replace('px', '')); var realLeft = parseInt(document.defaultView.getComputedStyle(dst, "").getPropertyValue('border-left-width').replace('px', '')); src.style.top = dst.offsetTop+dst.offsetParent.offsetTop+realTop + 'px'; src.style.left = dst.offsetLeft+dst.offsetParent.offsetLeft+realLeft + 'px'; } También elaborándolo un poco más, podrías usar getComputedStyle en todos los casos (incluído IE). Más info en: http://www.w3.org/2003/01/dom2-javadoc/org/w3c/dom/css/ViewCSS.html http://www.faqts.com/knowledge_base/view.phtml/aid/7157 http://annevankesteren.nl/2006/05/offset#comment-5377 http://www.setmajer.com/demo/find_position_test/js/main.js De todas formas, por lo que veo querés hacer algo bien genérico, no? Si el div que se posiciona encima tiene que adaptarse al tamaño y demás estilos visuales (como ser el borde) del elemento a pisar, no es mala idea lo que estás haciendo de 'camuflarlo' con el estilo destino. Saludos, Luis On 12/15/06, Fernando Tubio <[EMAIL PROTECTED]> wrote: (Primero disculpas al resto de la lista porque cuando envié el mensaje originalmente omití indicar que se trataba de un off-topic. ) Hola Luis, Gracias por contestar. Ya lo creo que es todo un tema, particularmente cuando se trata de hacer algo que funcione de igual forma en los browser más populares. En este caso especificar un float no me permitiría superponer un objeto sobre otro, y z-index me ayudaría solo en el caso de que los elementos ya se encuentren correctamente posicionados y superpuestos. Intentaré dar un ejemplo simplificado de lo que intento lograr. <html> <head> <style> #src { background-color:yellow; } #elt1 { background-color:#ffeeff; padding:40px; } #elt2 { border:solid 30px; padding:40px; } </style> <script> function moverAqui(dst) { var src = document.getElementById('src'); // parche para IE para forzar hasLayout dst.style.zoom = '1'; // esto es simplificado, ya que si el elemento se encontrara anidado dentro de // otros elementos posicionados habría que recorrer la jerarquia sumando los offsets src.style.position = 'absolute'; src.style.top = dst.offsetTop + dst.offsetParent.offsetTop + 'px'; src.style.left = dst.offsetLeft + dst.offsetParent.offsetLeft + 'px'; src.style.height = dst.clientHeight + 'px'; src.style.width = dst.clientWidth + 'px'; } </script> </head> <body> <h1 id="elt1" onclick="moverAqui(this);">Esto es un elemento cualquiera. Haga clic aqui!</h1> <h1 id="elt2" onclick="moverAqui(this);">Esto es otro elemento cualquiera. Haga clic aqui!</h1> <div id="src">ESTE ES EL ELEMENTO A POSICIONAR</div> </body> </html> Haciendo clic en cualquiera de los dos elementos, 'elt1' y 'elt2', posiciona el <div> sobre el elemento en cuestión. Como el elemento 'elt1' carece de borde, el div cubre el area de contenido correctamente. Sin embargo, el estilo del elemento 'elt2' indica un borde, y el div aparece en la posición incorrecta. Mi problema es encontrar la forma de encontrar las coordenadas del 'area interior' del elemento, por adentro del borde. No encuentro un mecanismo que me devuelva el ancho del borde en pixels y que funcione en forma 'cross-browser'. Por ahora encontré una alternativa que es copiar el estilo del elemento sobre el cual se va a posicionar, de tal forma que el div tenga el mismo borde. De esta forma el efecto visual es correcto. Pero estoy teniendo otros problemas con esta solución así que todavía no estoy seguro si es viable. Saludos, Fernando Tubio ----- Original Message ----- From: Luis Farzati To: puntonet@mug.org.ar Sent: Friday, December 15, 2006 6:46 PM Subject: [puntonet] Recuperar la posicion de un elemento HTML Hola Fernando, La obtención de las posiciones es todo un tema, tienen ciertas reglas que tienen que ver con la forma de renderear el elemento que tiene el browser. Si te posteás un pequeño ejemplo del problema concreto, como para que sea más visible, vemos cómo lo podemos encarar. Pero mi sugerencia es que, si lo que querés es superponer un objeto, pruebes combinando el float y z-index (o z-order?) del CSS. En mi experiencia siempre es conveniente esquivar posicionado absoluto, en lo posible. Saludos, Luis On 12/12/06, Fernando Tubio <[EMAIL PROTECTED]> wrote: Necesito posicionar un <div> en forma absoluta de tal forma que se superponga al area de contenido de un elemento en una página HTML, pero estoy encontrando dificultades en hallar un mecanismo que me devuelva las dimensiones necesarias. Puedo calcular las coordenadas del ángulo superior izquierdo del elemento sumando los valores de offsetLeft y offsetTop de la jerarquía de elementos contenedores, pero el resultado corresponde a las coordenadas del borde externo del elemento. Necesito las coordenadas del área de contenido, excluyendo bordes y padding. Internet Explorer posee las propiedades clientLeft y clientTop que podrían ser útiles, pero por desgracia no son estándar y no han sido implementadas en Mozilla por ejemplo, a pesar de que este último si dispone de clientWidth y clientHeight. Para determinar las dimensiones del borde + padding supongo que podría usar algo similar a (offsetWidth - clientWidth) / 2, pero esto asume que el borde y el padding son iguales en cada lado del elemento, y esto no siempre es el caso. Los valores disponibles a partir de la propiedad style no pueden ser usados para realizar el cálculo ya que sus unidades no son siempre uniformes. Se podría tener por ejemplo un valor para el ancho del borde expresado como 'thick' o '1em'. Necesito un valor expresado en pixels. ¿Alguna sugerencia? Saludos, Fernando Tubio