2012-03-22 16 views
5

Tengo varias imágenes en mi página. Para detectar imágenes rotas, utilicé esto encontrado en SO.Diferencia entre jQuery.one() y jQuery.on()

$('.imgRot').one('error',function(){ 
    $(this).attr('src','broken.png'); 
}); 

Esto funciona bien en la primera imagen que yo entiendo. Pero cuando cambio esto a

$('.imgRot').on('error',function(){ 
    $(this).attr('src','broken.png'); 
}); 

no funciona en ninguna de las imágenes. ¿Podría alguien decirme por qué?

Respuesta

6

Si mira el código fuente .one() en jQuery 1.7, simplemente llama a .on() internamente, excepto que después de que el evento se desencadena, elimina el controlador de eventos. Por lo tanto, no debería haber diferencia en su caso porque error es un evento que solo debería ocurrir una vez por objeto de todos modos.

Por lo tanto, debe haber algo más en su código como quizás los objetos de imagen no se hayan cargado en el DOM aún cuando ejecuta este código o algo así.

Si estaba intentando usar el manejo delegado de eventos para hacer esto (que su ejemplo no muestra), entonces puede encontrarse con problemas donde el evento 'error' no se propaga.

También es posible que el código tenga problemas de sincronización debido a la colocación en caché. Intentar instalar estos tipos de manejadores de errores en imágenes que ya están en DOM es una condición de carrera. Está intentando instalar el controlador de errores antes de que se le llame, pero la imagen ya comenzó a cargarse y es posible que el evento ya se haya activado antes de instalar el controlador de eventos. Las cargas de página posteriores (después del primero) pueden haber guardado en caché otros elementos de página o referencias de DNS para que puedan llegar al manejador de errores más rápido y quizás incluso antes de que su JS pueda ejecutarse e instalar los manejadores de errores.

Sé que esto es un problema con el almacenamiento en caché del navegador y el evento onload. Solo puede obtener el evento onload de forma confiable si conecta el controlador de eventos en el HTML incrustado (para que esté allí cuando la etiqueta <img> se analiza por primera vez o si la adjunta antes de que se haya establecido la propiedad .src (si se crea la imagen mediante programación). eso hace pensar que no se puede establecer de forma fiable error manipuladores de la forma en que está haciendo para las imágenes que se encuentran en la página HTML

Mi sugerencia sería la siguiente:.

  • no trate de instalar controladores de errores así después de que las imágenes estén en DOM.
  • Si las asigna en programmat generando imágenes, luego asigne los manejadores de eventos antes de asignar .src.
  • Si necesita estos en imágenes en el HTML de la página, tendrá que colocar los controladores de eventos en el HTML con algo como <img src="xxx" onerror="yourErrorFunc(this)"> porque esa es la única manera de garantizar que los controladores estén instalados antes de que el evento pueda ocurrir.
9

Wiki de la comunidad: Esta respuesta genérica no contribuye a la pregunta OP publicada pero relativa al título.

El concepto de uno() y en() se puede explicar con el código de abajo.

one() la función se mueve automáticamente a estado apagado después de la primera instancia de ocurrencia.

on() es idéntico a uno() pero debe ser desactivado manualmente, de lo contrario, el número de instancias no tiene límite.

var i = 1; 
 
$('.one').one('click', function() { 
 

 
    $(this).text('I am clickable only once: ' + i); 
 
    i++; 
 
}); 
 

 
var j = 1; 
 
$('.multiple').on('click', function() { 
 

 
    $(this).text('I was clicked ' + j + ' times'); 
 
    j++; 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div class="one">Click me</div> 
 
<div class="multiple">Click me</div>

0

jQuery volverá a utilizar el "sobre" método para el "uno". El siguiente es el código interno de jQuery donde van a estar pasando valor codificado "1" a la función de jQuery.on() Van a apagar el evento disparado aún más en el elemento utilizando jQuery.off()

on:function(types, selector, data, fn, one) { 

    if (one === 1) { 
      origFn = fn; 
      fn = function(event) { 
      jQuery().off(event); 
      return origFn.apply(this, arguments); 
      }; 

    } 
    off:function(types, selector, data, fn){ 
     on(types, selector, data, fn, 1); 
    } 

Por lo tanto, en su caso, "error" es el tipo de evento activado en la primera imagen y cuando el método jQuery.one() llamado este evento se desactiva y luego no se activa para el $ ('. ImgRot') elementos