Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Frontend samurai L'avatar di fcaldera
    Registrato dal
    Feb 2003
    Messaggi
    12,924

    Preload universale (non solo immagini) con Ajax

    Ciao a tutti,

    tempo fa in un thread è stato sollevato il problema di eseguire il preload di un file diverso da un immagine.

    Poichè il classico approccio

    obj = new Image()
    obj.src = ...
    obj.onload = ...

    non funziona con tutti i formati di file, vi propongo la mia soluzione, (a dir la verità abbastanza banale, ma non mi sembra che qualcuno l'abbia proposta ancora) che sfrutta ajax per eseguire una richiesta get ad una risorsa.

    Un esempio funzionante si trova qui
    http://www.fabriziocalderan.it/code/...oad/index.html

    in cui si trova un esempio e la spiegazione del codice che ho usato. La classe che ho creato (AJAXPreload) è prelevabile direttamente dal sorgente, Per comodità la riporto anche qui.

    Non ho inserito (per ora) la gestione degli errori, aspetto un vostro riscontro sul funzionamento generale del codice applicato a file di diverso tipo (mp3, ra, pdf...)

    Inoltre, per via delle limitazione dell'oggetto xmhttprequest il preload è possibile solo su file dello stesso dominio (limite accettabile nella maggior parte dei casi credo...)


    codice:
       <script type="text/javascript">
        // <![CDATA[
            
        function AJAXPreload() {
            
            var id = '';
            var uri = '';
            var attr = '';
            var clss = '';
            var XMLHttpReqObj = null;    
            
            this.setUri = function(this_uri) {
                uri = this_uri;
            }
            
            this.setElementOnLoad = function(this_id, this_attr) {
                id = this_id;
                attr = this_attr;
            }
            
            this.setClassOnLoad = function(this_class) {
                clss = this_class;
            }
                
            this.initPreload = function() {
                
                if (typeof XMLHttpRequest != "undefined") {
                    XMLHttpReqObj = new XMLHttpRequest();
                }
                else {
                    try {
                        XMLHttpReqObj = new ActiveXObject("Msxml2.XMLHTTP");
                    } catch (e) {
                        try {
                            XMLHttpReqObj = new ActiveXObject("Microsoft.XMLHTTP");
                        } 
                        catch (e) {
                            XMLHttpReqObj = null;
                        }
                    }
                }
                    
                if (!XMLHttpReqObj) {
                    return false;
                }
                else {
                    XMLHttpReqObj.open("GET", uri, true);
                    
                    XMLHttpReqObj.onreadystatechange = function() {
                    
                        switch (XMLHttpReqObj.readyState) {
                        case 0: // Uninitialized
                        case 1: // Loading
                        case 2: // Loaded
                        case 3: // Ready
                            break;
                        case 4:
                                
                            switch(XMLHttpReqObj.status) {
                                
                                case 200:
                                case 304:
                                    
                                    document.getElementById(id).setAttribute(attr, uri); 
                                    
                                    if (!(clss == '')) {
                                        document.getElementById(id).className = clss;
                                    }
                                    
                                    break;
                                    
                                case 0: // wrong protocol
                                    
                                default:
                                    // Catch exception for IE
                            }
                            
                            break;
                        }
                        
                    } // function onreadystatechange   
                    
                    XMLHttpReqObj.send(null);
                    delete XMLHttpReqObj;
                }
            }        
        }
            
        
        // ]]>
        </script>
    Ciao
    Vuoi aiutare la riforestazione responsabile?

    Iscriviti a Ecologi e inizia a rimuovere la tua impronta ecologica (30 alberi extra usando il referral)

  2. #2
    Utente di HTML.it L'avatar di pietro09
    Registrato dal
    Jan 2002
    Messaggi
    10,116
    Ho prelevato il codice e l'immagine e fatto una pagina di prova nel mio localhost.
    Ho qualche perplessità :master: Parlo di sensazioni perchè non ho i mezzi per verificare.
    Ho creato un pulsante ed ho messo il codice:
    document.getElementById("obj1").src = "empty_img_for_xhtml_validation.png";
    (da me si chiama così l'immagine prelavata dal tuo sito)


    Nella tua funzione commento:
    //document.getElementById(id).setAttribute(attr, uri);

    Ho pensato che quando il codice arriva lì, l'immagine è già stata scaricata in memoria (XMLHttpReqObj.status = 304)

    Premo il link di preload ed aspetto una diecina di secondi.
    Io penso che, se il preload è già fatto, il click del pulsante deve visulizzare l'immagine immediatamente
    Invece noto un certo tempo (breve) per il caricamento dell'immagine.

    Adesso, nell'evento load metto il classico:
    self.x = new Image(); x.src = "empty_img_for_xhtml_validation.png";

    carico la pagina, aspetto 10 secondi, clicco il pulsante, e l'immagine appare istantaneamente.

    Ecco perchè sono un poco perplesso

    Pietro

  3. #3
    Frontend samurai L'avatar di fcaldera
    Registrato dal
    Feb 2003
    Messaggi
    12,924
    i tempi di risposta sono corretti: considera che l'immagine da visualizzare è di oltre 900 kb è un certo tempo viene perso nel rendering e nel ridimensionamento dell'immagine da parte del browser

    inoltre la classe è già strutturata per rilevare il contenuto in cache. Anche questo rilevamento impiega un certo tempo (trascurabile, passa subito allo status 4) ma non hai altro modo di stabilire se un file sia in cache o meno (con js)

    Inoltre hai il vantaggio di fare preload non solo di immagini
    Vuoi aiutare la riforestazione responsabile?

    Iscriviti a Ecologi e inizia a rimuovere la tua impronta ecologica (30 alberi extra usando il referral)

  4. #4
    Utente di HTML.it L'avatar di pietro09
    Registrato dal
    Jan 2002
    Messaggi
    10,116
    Originariamente inviato da fcaldera
    i tempi di risposta sono corretti: considera che l'immagine da visualizzare è di oltre 900 kb è un certo tempo viene perso nel rendering e nel ridimensionamento dell'immagine da parte del browser

    inoltre la classe è già strutturata per rilevare il contenuto in cache. Anche questo rilevamento impiega un certo tempo (trascurabile, passa subito allo status 4) ma non hai altro modo di stabilire se un file sia in cache o meno (con js)

    Inoltre hai il vantaggio di fare preload non solo di immagini

    allora, prima di chiudere, ho provato con firefox.
    Con la classe ajax, vedo il caricamento dell'immagine dall'alto in basso, come se la stesse caricando.
    Col metodo tradizionale vedo l'immagine istantaneamente e non noto il caricamento dall'alto in basso.

    Insomma, credo proprio che nel mio computer non avvenga il preload, con ajax
    Pietro

  5. #5
    Frontend samurai L'avatar di fcaldera
    Registrato dal
    Feb 2003
    Messaggi
    12,924
    altre impressioni / prove ?
    Vuoi aiutare la riforestazione responsabile?

    Iscriviti a Ecologi e inizia a rimuovere la tua impronta ecologica (30 alberi extra usando il referral)

  6. #6
    ciao,
    ho provato a usare la tua funzione ma senza successo...
    in pratica in una pagina devo caricare un'immagine molto pesante (è una mappa) e nella parte alta della pagina ho una serie di bottoni che caricano ognuno una determinata funzione js.
    se però l'utente clicca sui bottoni prima che l'immagine si sia caricata la funzione non funge...
    quindi volevo caricare l'immagine in maniera asincrona e al posto dell'immagine che devo caricare metto un'immagine da un pixel estesa.

    questo è il codice:
    codice:
    [img]../mura/image/pixel.gif[/img]
    e in una funzione chiamata con il metodo onload ho messo:
    codice:
    ...
    objpreload1 = new AJAXPreload();
    objpreload1.setElementOnLoad('ajaxmap', 'src');
    objpreload1.setClassOnLoad('img_loaded border');
    objpreload1.setUri('../image/map.png');
    objpreload1.initPreload();
    oltre alla funzione AjaxPreload.

    però l'unica cosa che vedo al caricamento della pagina è il pixel esteso...
    la console javascript dà questo errore:

    this.anchor has no properties

    su questa istruzione:

    this.anchor.parentObject = this;

    riferito ad un'altra funzione che ho, prima di mettere il codice sopra non lo dava...
    qualche idea????

  7. #7
    Ciao fcaldera, ciao a tutti
    sto usando il metodo classico che descrivi in alto per ottenere il preload delle immagini.

    Preferirei non ricorrere ad ajax visto che devo precaricare appunto delle immagini.

    se uso questo sistema tutto funziona

    codice:
    function change(img){
    	var el=document.getElementById("fotoplace");
    	el.src="images/load.gif"; //prima della nuova immagine mostro il preload
    
    
    	var obj = new Image();
    	obj.src=img;
    	obj.onload=rimpiazza(img);
    }
    function rimpiazza(img){
            var el=document.getElementById("fotoplace");
    	el.src=img;
    }
    purtroppo non posso usare questo sistema per vari motivi, ho quindi buttato giù questa variante:

    codice:
    function change(img){
    //mostro il div preload
    	var el=document.getElementById("preload");
    	el.style.visibility="visible";
    
    //carico l'immagine
    	var obj = new Image();
    	obj.src=img;
    	obj.onload=rimpiazza(img);
    }
    function rimpiazza(img){
    //nascondo il preload
    	var el1=document.getElementById("preload");
    	el1.style.visibility="hidden";
    //mostro la nuova immagine
    	var el=document.getElementById("fotoplace");
    	el.src=img;
    }
    Con questo sistema il div contenente il preload non viene mai mostrato, si passa dalla vecchia alla nuova immagine e basta.........

    Come si spiega?

    Grazie
    Luca

  8. #8
    così funziona:
    codice:
    var image=""
    function change(img){
    	image=img;
    	document.getElementById("preload").style.visibility="visible";
    	var obj = new Image();
    	obj.src=img;
    	obj.onload=function(image){
    		document.getElementById("fotoplace").src=img;
    		document.getElementById("preload").style.visibility="hidden";
    	}
    }
    grazie lo stesso

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.