2012-02-03 9 views
28

Por lo tanto, necesito saber el ancho de un elemento con javascript, el problema que tengo es que la función se dispara demasiado pronto y el ancho cambia cuando el css se aplica tottally. Según entendí, la función $ (document) .ready() se activó cuando se completó el documento, pero parece que no funciona así.

De todas formas, estoy seguro de que con el código de mi problema se entenderá (este es un ejemplo simplificado):

<html> 
<head> 
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> 
    <link href='http://fonts.googleapis.com/css?family=Parisienne' rel='stylesheet' type='text/css'> 

    <style type="text/css"> 
     #target { 
      font-family: 'Parisienne', cursive; 
      float: left; 
     } 
    </style> 
</head> 
<body> 
    <div id="target">Element</div> 
</body> 
</html> 

<script type="text/javascript"> 
    $(document).ready(function(){ 
     console.debug($('#target').outerWidth()); 
     alert('hold on'); 
     console.debug($('#target').outerWidth()); 
    }); 
</script> 

Quiero saber el ancho de la div #target, el problema es que el código que se ejecuta antes de la alerta da un resultado diferente que el siguiente, presumiblemente porque la fuente no está completamente cargada y está midiendo el div con la fuente predeterminada.

Funciona como esperaba en Google Chrome, pero no en IE y Firefox.

+0

puedo confirmar 24/11/2013 que este problema todavía existe en jQuery 2.x cuando se pulse el botón de actualización del navegador. Vaya a este [violín] (http://jsfiddle.net/jLDbX/). Cuando cargue el violín por primera vez, todo debería funcionar bien la mayoría de las veces. También funciona si coloca el cursor de su mouse en la URL y pulsa enter. Pero las cosas se irán al infierno si haces clic en el botón de actualización o presionas * CTRL + R *. –

+0

Intenté implementar un "bloqueo de cuenta regresiva" para medir el ancho y la altura solo cuando tanto la carga de ventana disparada como las fuentes dependientes terminaron el disparo. Vea si esto ayuda: [http://jsfiddle.net/jLDbX/1/](http://jsfiddle.net/jLDbX/1/). En este violín, todo parece estar funcionando bien. Pero en mi aplicación en el mundo real, seguí recibiendo errores. Sin embargo, para ti, podría funcionar. –

Respuesta

58

Si depende de contenido externo a ya se pueden cargar imágenes (por ejemplo, fuentes), es necesario utilizar el evento window.load

$(window).load(function() { 
    // code here 
}); 

El comportamiento de estos eventos se describe en this article.

+5

¡Dos años después, sigue siendo útil! – statue

+5

En JQuery 3.0, debe usar la sintaxis '$ (ventana) .on ('load', function() { });' dado que $ (window) .load() está en desuso. –

+0

@AlexH, buen punto. '$ (window) .load()' quedó en desuso en jQuery 1.8. Además, es confuso porque hay dos métodos '.load()' en jQuery (antes de que se eliminara el manejo de eventos). – ryanpcmcquen

9

Cita OP:

"Según entendí, la función $(document).ready() fue despedido cuando se ha completado el documento,"

$(document).ready() incendios cuando el ("modelo de objetos de documento DOM ") está completamente cargado y listo para ser manipulado. El DOM no es lo mismo que el "documento".

W3C - DOM Frequently Asked Questions

Usted puede intentar $(window).load() función en lugar ...

$(window).load(function() { 
    // your code 
}); 

Se esperará a que todos los activos de la página (como imágenes y fuentes, etc.) se cargue por completo antes de disparar.

3

La función jQuery .ready() se dispara tan pronto como se completa el DOM. Eso no significa que todos los activos (como imágenes, CSS, etc.) se hayan cargado en ese momento y, por lo tanto, el tamaño de los elementos está sujeto a cambios.

Use $ (ventana) .load() si necesita el tamaño de un elemento.

1

Puede usar $(window).load(), pero eso esperará a todos los recursos (por ejemplo, imágenes, etc.). Si sólo desea esperar a que la fuente se va a cargar, podría intentar algo como esto:

<script type="text/javascript"> 
    var isFontLoaded = false; 
    var isDocumentReady = false; 
    $("link[href*=fonts.googleapis.com]").load(function() { 
     isFontLoaded = true; 
     if (isDocumentReady) { 
      init(); 
     } 
    }); 
    $(document).ready(function() { 
     isDocumentReady = true; 
     if (isFontLoaded) { 
      init(); 
     } 
    }); 
    function init() { 
     // do something with $('#target').outerWidth() 
    } 
</script> 

de responsabilidad: No estoy totalmente seguro de que esto funcionará. El evento de carga <link> puede activarse tan pronto como se analice la hoja de estilo, pero antes de que se hayan descargado sus recursos externos. Tal vez podría agregar un <img src="fontFile.eot" /> oculto y poner su controlador de carga en la imagen en su lugar.

2

El evento "listo" se activa cuando se carga DOM, lo que significa que es posible trabajar de forma segura con el marcado.

Para esperar a que se carguen todos los activos (css, images, javascript externo ...), preferiría usar el evento load.

$(window).load(function() { 
    ... 
}); 
1

He visto repetidamente el mismo problema en IE9 e IE10. La llamada a jquery ready() se dispara y uno de mis < div> 's no existe. Si detecto eso y luego vuelvo a llamar después de un breve tiempo de espera(), funciona bien.

Mi solución, sólo para estar seguro, era doble:

  1. Añada una < script> window.fullyLoaded = true; </script> al final del documento a continuación, comprobar para esa variable en la devolución de llamada listo(), y

  2. Comprobar si $ ('# lastElementInTheDocument'). Longitud> 0

Sí, Reconozco que estos son hacks desagradables. Sin embargo, cuando ready() no está funcionando como se esperaba, se necesita algún tipo de solución.

Por un lado, la solución "correcta" probablemente implique establecer $ .holdReady en el encabezado, y borrarlo al final del documento. Pero, por supuesto, la solución realmente correcta es ready() para funcionar.

+0

Creo que estoy viendo este comportamiento también. Tal vez la solución es poner el comando document.ready en la parte inferior de la página, que parece ser una práctica más común en estos días. Estoy viendo este problema, pero ahora tengo mi comando document.ready en la etiqueta . – hairbo

1

El problema $ (document) .ready() se dispara demasiado pronto puede suceder a veces porque ha declarado la función jQuery onReady incorrectamente.

Si tiene problemas, asegúrese de que su función se declara exactamente así:

$(document).ready(function() 
{ 
    // put your code here for what you want to do when the page loads. 
}); 

Por ejemplo, si se le ha olvidado la parte función anónima, el código seguirá funcionando, pero se ejecutará "fuera de orden".

console.log('1'); 
$(document).ready() 
{ 
    console.log('3'); 
} 
console.log('2'); 

esta voluntad de salida

1 
3 
2 
Cuestiones relacionadas