..."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 






Responder a