Estoy cargando imágenes (grandes) dinámicamente para dibujar en un lienzo html5, algo como esto:
var t = new Image(); t.onload = ... t.src = 'http://myurl';Pero de vez en cuando me gustaría cancelar la solicitud de imagen por completo.
La única forma en que se me ocurrió es establecer src en '' . es decir
t.src = ''Esto funciona en muchos navegadores, pero parece que solo Firefox cancela la solicitud http de la imagen.
Probé esto con Fiddler2 al deshabilitar el almacenamiento en caché y habilitar "emular la velocidad del módem". Luego, ejecute un violín para probar la cancelación de una solicitud de imagen. (Me encantaría escuchar otras ideas sobre cómo probar esto)
Sé que hay formas de cancelar todas las solicitudes ( como en esta pregunta ), pero me gustaría cancelar solo una.
¿Alguna idea sobre otras formas (especialmente en navegadores móviles) para hacer esto?
Esta es la única forma en que logré que funcionara en todos los navegadores modernos (Chrome, Safari, Mobile-Safari, Firefox e IE9).
iframe vacío y ocultoimage tag al body en el iframeimg.onload , puede usar ese elemento dom de imagen para dibujar en un lienzo html5 con drawImage()stop() en contentWindow del iframe (o execCommand("stop", false) en contentDocument en IE).Creé una clase para esto y puse el código de coffeescript (y está compilado javascript) en github: Cancelable Html5 Image Loader
Si quieres jugar con él, también creé un jsfiddle para probarlo . Recuerde iniciar Fiddler2 (o algo similar) para ver que la solicitud de red real realmente se cancela.
Puede probar window.stop() para detener todas las solicitudes, pero no las individuales. En IE, no es window.stop() es document.execCommand("Stop", false).
Si tiene otras cosas en marcha en cuanto a la solicitud, entonces hacer esto interferirá con eso. (Haría un seguimiento con una nueva solicitud de los recursos que aún desea, pero eso se parece demasiado al trabajo duro).
Entonces, si quisiera detener una sola solicitud de una imagen grande, lo que podría hacer es cargar la imagen en un documento dentro de un IFRAME oculto. El evento de carga del IFRAME se puede usar para cargar la imagen en el documento principal, momento en el que debería almacenarse en caché (suponiendo que tenga las directivas de almacenamiento en caché configuradas para hacerlo).
Si la imagen tarda demasiado, puede acceder a la ventana de contenido de IFRAME y emitir un comando de detención.
Debe tener tantos elementos IFRAME como imágenes que se pueden solicitar simultáneamente.
De hecho, tengo el mismo problema e hice algunas pruebas.
He hecho algunas pruebas con iframes y tengo cierto éxito. Probado en Firefox 3.6 y Chrome. Para las pruebas utilicé 9 imágenes de 15Mb . Con la precarga de img, eliminé mi firefox varias veces (sí, no hay mucha memoria en esta computadora), usar img la acción "suspender" no evita que se cargue la imagen si la solicitud ha comenzado, con iframes la acción de suspensión realmente detiene la descarga (como yo quitar el iframe). El siguiente paso será probar con XMLHttpRequests . Como esta versión de mi código de prueba está utilizando el comportamiento de la memoria caché del navegador desde la URL de la imagen para evitar una segunda carga y esto también funciona con las solicitudes de ajax. Pero tal vez con iframes podría encontrar una manera de recuperar datos binarios de la imagen cargada en iframe directamente (con limitación en las URL del mismo dominio).
Este es mi código de prueba (muy rápido en Chrome, puede matar tu Firefox con demasiadas imágenes muy grandes):
// jQuery.imageload.shared.list contains an array of oversized images url jQuery.each(imglist,function(i,imgsrc) { name = 'imageload-frame'; id = name + "-" + i; // with img it is not possible to suspend, the get is performed even after remove //var loader = jQuery('<img />').attr('name', name).attr('id',id); var loader = jQuery('<iframe />').attr('name', name).attr('id',id); //no cache on GET query taken from jQuery core // as we really want to download each image for these tests var ts = +new Date; // try replacing _= if it is there var ret = imgsrc.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2"); // if nothing was replaced, add timestamp to the end imgsrc = imgsrc + ((ret == imgsrc) ? (imgsrc.match(/\?/) ? "&" : "?") + "_=" + ts : ""); loader.css('display', 'none').appendTo('body'); loader.after( jQuery('<a>') .text(' stop ') .attr('href','#') .click(function(){ loader.remove(); jQuery(this).text(' suspended '); }) ); // start the load - preload loader.attr('src',imgsrc); // when preload is done we provide a way to get img in document loader.load(function() { jQuery(this).next("a:first") .text(" retrieve ").unbind('click') .click(function() { var finalimg = jQuery('<img />'); // browser cache should help us now // but there's maybe a way to get it direclty from the iframe finalimg.attr('src',loader[0].src); finalimg.appendTo('body'); }); }); });editar y aquí está el relleno para probarlo: http://jsfiddle.net/wPr3x/