2011-04-26 46 views
41

¿Alguien sabe si existe tal cosa?jQuery iframe load() event?

Tengo un iframe que está siendo insertado con $.ajax() y quiero hacer algunas cosas después de que los contenidos del marco flotante son completamente cargado:

.... 
success: function(html){ // <-- html is the IFRAME (#theiframe) 
      $(this).html(html); // $(this) is the container element 
      $(this).show(); 
      $('#theiframe').load(function(){ 
      alert('loaded!'); 
      } 
.... 

funciona, pero no veo el IFRAME se carga dos veces (la alerta también muestra dos veces).

+0

intente configurar el src del iframe antes de anexarlo al DOM. Esto debería evitar que el evento de carga se dispare dos veces. – Abe

Respuesta

47

Si es posible, sería mejor controlar el evento load dentro del documento del marco flotante y llamando a una función en el documento que contiene. Esto tiene la ventaja de funcionar en todos los navegadores y solo se ejecuta una vez.

En el documento principal:

function iframeLoaded() { 
    alert("Iframe loaded!"); 
} 

En el documento marco flotante:

window.onload = function() { 
    parent.iframeLoaded(); 
} 
+0

hey this works! pero ¿cómo puedo llamar a una función que está dentro de la función 'jQuery (document) .ready' del documento principal? – Alex

+0

@Alex: deberá asegurarse de que la función sea global, lo que puede hacer declarándola como una variable en el ámbito global antes de asignar un valor a la variable dentro de su función 'ready()', o de forma explícita asignándola como una propiedad de 'window' dentro de su función' ready() '. Por ejemplo: '$ (document) .ready (function() {window.iframeLoaded = function() {alert (" Load ");};/* Otras cosas aquí * /})'; –

+0

parece que mi problema de doble carga es que envuelve el iframe entre las etiquetas DIV. Para algunos navegadores de razón raros, vuelva a cargar el iframe si hace esto ... – Alex

2

Usted puede utilizar el método de la jQuery Contents para obtener el contenido del iframe.

3

Ese es el mismo comportamiento que he visto: iframe's load() disparará primero en un iframe vacío, luego la segunda vez cuando se carga su página.

Editar: Hmm, interesante. Puede incrementar un contador en su controlador de eventos, y a) ignorar el primer evento load, o b) ignorar cualquier evento load duplicado.

+0

si agrego 'alert ($ (this) .attr ('src'));' dentro de la función de carga obtengo el mismo valor dos veces ... – Alex

2

Si usted quiere que sea más genérico e independiente, puede utilizar cookies. El contenido de Iframe puede establecer una cookie. Con jquery.cookie y un temporizador (o en este caso el temporizador de JavaScript), puede verificar si la cookie se establece cada segundo más o menos.

//token should be a unique random value which is also sent to ifame to get set 
iframeLoadCheckTimer = window.setInterval(function() { 
     cookieValue = $.cookie('iframeToken'); 
     if (cookieValue == token) 
     { 
      window.clearInterval(iframeLoadCheckTimer); 
      $.cookie('iframeToken', null, { 
       expires: 1, 
       path: '/' 
     }); 
     } 
}, 1000); 
6

A lo largo de las líneas de Tim Down's answer pero aprovechando jQuery (mencionado por el PO) y sin apretar el acoplamiento de la página que contiene y el iframe, puede hacer lo siguiente:

En el marco flotante:

<script> 
    $(function() { 
     var w = window; 
     if (w.frameElement != null 
       && w.frameElement.nodeName === "IFRAME" 
       && w.parent.jQuery) { 
      w.parent.jQuery(w.parent.document).trigger('iframeready'); 
     } 
    }); 
</script> 

En la página que contiene:

<script> 
    function myHandler() { 
     alert('iframe (almost) loaded'); 
    } 
    $(document).on('iframeready', myHandler); 
</script> 

la IFRA me dispara un evento en el documento de la ventana primaria (potencialmente existente) - tenga en cuenta que el documento padre necesita una instancia de jQuery para que funcione. Luego, en la ventana principal, adjuntas un controlador para reaccionar ante ese evento.

Esta solución tiene la ventaja de no romper cuando la página que contiene no contiene el controlador de carga esperada. En términos más generales, no debería ser la preocupación del iframe conocer el entorno que lo rodea.

Tenga en cuenta, que estamos aprovechando el evento ready DOM para desencadenar el evento - que debería ser adecuado para la mayoría de los casos de uso.Si no lo es, simplemente conecte la línea de evento de disparo de evento de carga de la ventana, así:

$(window).on('load', function() { ... }); 
+0

Esta es la única solución que funcionó para mí. Me niego a usar una cookie para manejar esto. – veksen

33

uso iframe onload event

$('#theiframe').on("load", function() { 
    alert(1); 
}); 
+3

A partir de JQuery 1.7 (noviembre de 2011), se supone que debes usar '$ ('# theiframe'). On (" cargar ", función())'. – Teepeemm

+5

No funciona con jQuery v2.1.3 –

+4

Parece que esto no se dispara. – Primus202

2

Sin código en iframe + animado:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> 
<script language="javascript" type="text/javascript"> 

function resizeIframe(obj) { 

    jQuery(document).ready(function($) { 

     $(obj).animate({height: obj.contentWindow.document.body.scrollHeight + 'px'}, 500) 

    }); 

}  
</script> 
<iframe width="100%" src="iframe.html" height="0" frameborder="0" scrolling="no" onload="resizeIframe(this)" >