Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1
    Utente di HTML.it L'avatar di iko82
    Registrato dal
    Apr 2007
    Messaggi
    63

    Come prototype estende il DOM

    Ciao, mi sto spaccando la testa da giorni per capire come la libreria prototype riesce ad estendere il dom...
    In particolare mi riferisco al poter agganciare le funzioni hide(), show() ecc ecc ai div o ad ogni altro elemento...

    Nel mio codice ho per esempio:

    <div id="my_div">
    FRED TEST!!
    </div>

    Grazie a prototype posso fare:

    $("my_div").hide();

    e chiamare il metodo hide() sul div my_div.
    Ho cercato in tutti i modi di replicare questo comportamento ma non ci sono riuscito...

    Qualche aiuto??

    Grazie
    Ciao
    Fede

  2. #2
    Utente di HTML.it L'avatar di Xinod
    Registrato dal
    Sep 2000
    Messaggi
    13,649
    ti consiglio di studiare il codice proposto qui
    http://www.dustindiaz.com/roll-out-your-own-interface/
    perche' emula bene certi processi che sono presenti in librerie piu' complesse
    (namespace con metodi privati e chainability, prima di tutto)

    ciao

  3. #3
    Utente di HTML.it L'avatar di iko82
    Registrato dal
    Apr 2007
    Messaggi
    63
    Originariamente inviato da Xinod
    ti consiglio di studiare il codice proposto qui
    http://www.dustindiaz.com/roll-out-your-own-interface/
    perche' emula bene certi processi che sono presenti in librerie piu' complesse
    (namespace con metodi privati e chainability, prima di tutto)

    ciao
    Grazie, lo sto guardando... Mi è ancora un po oscura la tecnica... Conosci magari altri link dove viene spiegato un po più in dettaglio?
    Io purtroppo non trovo quasi niente a questi livelli...

  4. #4
    Per estendere gli elementi HTML il modo migliore sarebbe manipolare l'HTML.prototype, ma visto che in IE tale metodo non funziona il team di prototype si è 'inventato' un modo per scavalcare il problema;
    andando molto per la sintesi il metodo utilizzato è simile a questo:
    codice:
    function $(id) {
      var el = document.getElementById(id);
      for(var i in $.methods) {
        if(typeof($.methods[i]) == 'function')
          el[i] = $.methods[i];
      }
    }
    
    $.methods = {
      'test': function() {
        alert(this.tagName);
      }
    }
    In questo modo tutti i metodi di $.methods vengono aggiunti a tutti gli oggetti chiamati con $.
    L'approccio usato da prototype è però uno dei più invasivi; personalmente preferisco un approccio alla jquery:
    codice:
    function $(id) {
      return new $.klass(document.getElementById(id));
    }
    
    $.klass = function(el) {
      this.el = el;
    }
    
    $.class.prototype = {
      'test': function() {
        alert(this.tagName);
      }
    }
    Tra l'altro quest'ultimo approcio permette con qualche opportuna modifica di manipolare anche più elementi html in una volta.

  5. #5
    Utente di HTML.it L'avatar di iko82
    Registrato dal
    Apr 2007
    Messaggi
    63
    Originariamente inviato da Mega69
    Per estendere gli elementi HTML il modo migliore sarebbe manipolare l'HTML.prototype, ma visto che in IE tale metodo non funziona il team di prototype si è 'inventato' un modo per scavalcare il problema;
    andando molto per la sintesi il metodo utilizzato è simile a questo:
    codice:
    function $(id) {
      var el = document.getElementById(id);
      for(var i in $.methods) {
        if(typeof($.methods[i]) == 'function')
          el[i] = $.methods[i];
      }
    }
    
    $.methods = {
      'test': function() {
        alert(this.tagName);
      }
    }
    Grazie per la spiegazione... Questo codice effettivamente l'ho capito MA provandolo non funziona...

    Se provo questo codice:

    codice:
    <div id="my_div">
                FRED TEST!!            
    </div>
    
    
    <script language="javascript">
    
    function $(id) {
      var el = document.getElementById(id);
      for(var i in $.methods) {
        if(typeof($.methods[i]) == 'function')
          el[i] = $.methods[i];
      }
    }
    
    $.methods = {
      'test': function() {
        alert(this.tagName);
      }
    }
    
    $("my_div").test();
    
    </script>
    Ottengo un

    codice:
    Exception: $("my_div") has no properties File
    Ignoro qualcosa di elementare??

  6. #6
    Ah scusa, per la fretta mi sono dimenticato che ovviamente la funzione deve anche ritornare l'oggetto:
    codice:
    function $(id) {
      var el = document.getElementById(id);
      for(var i in $.methods) {
        if(typeof($.methods[i]) == 'function')
          el[i] = $.methods[i];
      }
      return el;
    }
    In ogni caso questo è solo un esempio: se vuoi applicarlo andrebbero fatti vari miglioramenti ( ad esempio verificare se l'elemento ha già i metodi in modo da non doverli nuovamente applicare... )

    Comunque ti ripeto, è molto meglio questo approccio:
    Codice PHP:
    function $(id) {
      return new $.
    klass(document.getElementById(id));
    }

    $.
    klass = function(el) {
      
    this.el el;
    }

    $.
    klass.prototype = {
      
    'test': function() {
        
    alert(this.el.tagName);
      }


  7. #7
    Utente di HTML.it L'avatar di iko82
    Registrato dal
    Apr 2007
    Messaggi
    63
    Originariamente inviato da Mega69
    Comunque ti ripeto, è molto meglio questo approccio:
    Codice PHP:
    function $(id) {
      return new $.
    klass(document.getElementById(id));
    }

    $.
    klass = function(el) {
      
    this.el el;
    }

    $.
    klass.prototype = {
      
    'test': function() {
        
    alert(this.el.tagName);
      }

    Mi sapresti spiegare nel concreto perchè ritieni sia meglio questo? Voglio dire... Cosa intendi per meno invasivo?
    Inoltre cosi facendo questi metodi si possono applicare solo se uso la funzione $() mentre se passo per document.getElementById() no. Mi sapresti dire come è possibile renderli disponibili anche senza passare per la funzione $() ?

    Grazie
    Ciao
    Fede

  8. #8
    Originariamente inviato da iko82
    Mi sapresti spiegare nel concreto perchè ritieni sia meglio questo? Voglio dire... Cosa intendi per meno invasivo?
    Inoltre cosi facendo questi metodi si possono applicare solo se uso la funzione $() mentre se passo per document.getElementById() no. Mi sapresti dire come è possibile renderli disponibili anche senza passare per la funzione $() ?

    Grazie
    Ciao
    Fede
    Meno invasivo te lo spiego subito.
    Immagina che io faccio una libreria che fa certe cose e per farle aggiungo dei metodi agli elementi html.
    Immagina che tu crei un altra libreria e anche tu aggiungi dei metodi agli HTMLElement.
    La situazione peggiore è quella in cui due o più metodi delle nostre librerie fanno la stessa cosa ( o peggio ancora cose diverse ) e si chiamano allo stesso modo.
    Ora, se per qualche motivo un terzo malcapitato avrà la necessità di usare tutte e due le librerie, rischierà di non vederle funzionare proprio perchè la seconda libreria sovrascriverà se necessario i metodi della prima.

    Esistono poi altri vantaggi. Il primo è che è molto più veloce utilizzare una classe con tutti i metodi ereditati dal prototype piuttosto che dover ogni volta fare un ciclo.

    Il secondo è che è possibile modificare leggermente lo script per operare contemporaneamente con più elementi; in jQuery ad esempio è possibile una cosa del genere:
    Codice PHP:
    $("a").attr("href""javascript:void(0);"
    L'unico "svantaggio" come dici tu è che in questo modo i metodi sono disponibili solo richiamando la funzione $; d'altra parte una volta creata una funzione come $ difficilmente torni al document.getElementById

  9. #9
    Utente di HTML.it L'avatar di iko82
    Registrato dal
    Apr 2007
    Messaggi
    63
    Originariamente inviato da Mega69
    Esistono poi altri vantaggi. Il primo è che è molto più veloce utilizzare una classe con tutti i metodi ereditati dal prototype piuttosto che dover ogni volta fare un ciclo.
    Riassumendo se non ho capito male quindi, ogni volta che "richiami" con la funzione $() un oggetto a questo "aggiungi" i metodi del prototype klass. SOLO ed esclusivamente quando e per gli oggetti che richiami in questo modo.
    Mentre invece prototype cicla su tutti gli elementi del dom in modo da poter rendere disponibili i metodi anche richiamando gli elementi in metodi canonici?

  10. #10
    Originariamente inviato da iko82
    Riassumendo se non ho capito male quindi, ogni volta che "richiami" con la funzione $() un oggetto a questo "aggiungi" i metodi del prototype klass. SOLO ed esclusivamente quando e per gli oggetti che richiami in questo modo.
    Mentre invece prototype cicla su tutti gli elementi del dom in modo da poter rendere disponibili i metodi anche richiamando gli elementi in metodi canonici?
    No attento; l'approccio di jQuery non tocca in alcun modo gli oggetti html. I metodi appartengono alla classe $.klass.
    La libreria Prototype.js aggiunge i metodi ma SOLO dopo aver richiamato l'oggetto con la funzione $.
    Quella del ciclo è un'idea apparentemente geniale ma in realtà pessima che nessuna libreria mette in pratica ( una via simile si potrebbe percorrere utiizzando HTMLElement.prototype, ma uno script .htc dovrebbe preoccuparsi di rendere lo script compatibile anche con IE ).

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.