Pagina 2 di 3 primaprima 1 2 3 ultimoultimo
Visualizzazione dei risultati da 11 a 20 su 24

Hybrid View

  1. #1
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,780
    Ciao, giusto un consiglio per arrivare a capire dove può risiedere il problema:

    fai un console.log della variabile "i" dentro la funzione mostra() e vedi cosa salta fuori
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  2. #2
    Quote Originariamente inviata da KillerWorm Visualizza il messaggio
    fai un console.log della variabile "i" dentro la funzione mostra() e vedi cosa salta fuori
    i viene vista come Object pointer event, mentre nel codice con onclick col valore corrispondente all'id del td cliccato.

  3. #3
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,780
    i viene vista come Object pointer event
    esatto... prova a chiederti il perché. Nel tuo script, non stai passando alcun valore alla funzione mostra. Come potrebbe arrivargli il valore "i"?

    Qui la documentazione:
    EventTarget.addEventListener()

    guarda come puoi impostare il listener, ci sono varie sintassi in cui la funzione può ricevere da uno a tre parametri.

    Prova a capire da te stesso; se hai bisogno, chiedi pure.
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  4. #4
    Quote Originariamente inviata da KillerWorm Visualizza il messaggio
    Nel tuo script, non stai passando alcun valore alla funzione mostra.
    Mi sono basato sul funzionamento di script come il seguente, dove la funzione è invocata senza un argomento, mentre è implementata con l'evento, la cui analisi permette di accettare soltanto lettere minuscole.
    codice:
        let mioNome = document.getElementById("myName");
        mioNome.addEventListener("keypress", checkName); // funzione invocata solo "di nome"
    
    
        function checkName(evento) { // funzione con argomento l'evento analizzato nella prima istruzione
          let charCode = evento.charCode; // recuperiamo il codice carattere dell'evento, cioè del tasto premuto (keypress)
    
    
          if (charCode !== 0) {
    
    
            if (charCode < 97 || charCode > 122) {
              evento.preventDefault(); // "annullo" l'evento, come se non avessi premuto il tasto
              alert("Per favore usa solo lettere minuscole!");
            }
    
    
          }
    
    
        }
    Uno script come un altro, ne ho tanti altri a dimostrare che la funzione va invocata soltanto per nome e l'evento resta catturato nell'argomento aggiunto implementandola.
    La mia perplessità è perché non ci sia linearità funzionale nell'addEventListener(), che si aveva con gli eventi dichiarati nell'elemento del DOM, dato che invia al worker di turno l'evento ma soltanto quando gli pare lo rende gestibile; cioè, in quanto contesto di programmazione, la cosa mi stona.
    Mi leggo comunque la documentazione e vedo di capirci qualcosa.

  5. #5
    Ho trovato che per passare parametri come argomenti conviene utilizzare una funzione anonima che invochi la funzione finale con l'argomento incluso (come fatto in altri casi in cui mostra(i) è invocata in coda ad altre funzioni:
    codice:
          for (i = 0; i < dvd.length; i++) {
            document.getElementById(i).addEventListener("click", function() {
              mostra(i);
            });
          }
    Tuttavia il risultato non cambia: i click nei td causano un errore nel getElementsByTagName perché la i è passata come Object pointer event che fino a ieri manco sapevo esistesse.
    Pare che l'unico modo per risolvere sia passare manualmente gli id testuali per ciascun td, ma in tal caso perdo la parametrizzazione su un file XML con una quantità differente di informazioni.

  6. #6
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,780
    Parliamo di programmazione ad oggetti; se non hai ben chiari alcuni principi fondamentali, rischi di addentrarti nella selva oscura senza capire quale possa essere il giusto sentiero per uscirne indenne e vincitore.

    Se hai un po' di pazienza, cerco di riassumere in maniera umana una lezione di "Principi di OOP JavaScript" in relazione a quanto discusso finora.
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  7. #7
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,780
    Col tuo ultimo script ti sei avvicinato ad una possibile soluzione, però in quel caso la variabile "i" non può essere valutata correttamente.

    L'evento è asincrono per definizione, quindi la funzione, che hai definito come listener, viene eseguita in maniera differita, NON al momento in cui la variabile "i" assume il relativo valore dell'iterazione corrente nel ciclo.

    Per questo motivo, quando tale funzione è eseguita, il ciclo è già terminato da un pezzo e la variabile "i" risulterà avere l'ultimo valore acquisito che ha determinato la conclusione del ciclo.

    La variabile "i" resta in "vita" (allocata in memoria) dentro lo scope del ciclo, proprio perché è referenziata nella tua funzione che hai definito nello stesso scope del ciclo.

    Capisco bene che certi meccanismi non siano semplici da comprendere ma, credimi, analizzando la situazione nel giusto contesto di programmazione ad oggetti, si può arrivare a capire che tutto è più che lineare.

    Considerando i tuoi script iniziali, provo a chiarire alcuni punti, per quel che riesco.

    Partiamo da questo:
    codice:
    "<tr><td onclick='mostra(" + i + ")'>"
    Come già ti è stato indicato, questa stringa deve essere "aggiunta" al DOM perché risulti funzionante e manipolabile a livello di script.

    Una volta interpretata attraverso JavaScript, e inserita nel documento, avrai un codice HTML del genere:
    codice:
    <tr><td onclick="mostra(1)">...
    che allo stesso tempo viene "convertito" in corrispettivi oggetti (elementi del DOM) che risiederanno da qualche parte dentro l'oggetto principale document.

    Ricorda, in un documento HTML e nell'ambito JavaScript, tutto si basa sugli "oggetti". Inutile dirlo, un oggetto (istanza di una classe) è un insieme di proprietà (dati, che possono essere anche altri oggetti) e di metodi (funzioni e relativo codice).

    A questo punto nel DOM hai sostanzialmente un oggetto TR (con sue proprietà e metodi) che contiene un oggetto TD (con sue proprietà e metodi).

    Molto a grandi linee, ogni elemento del DOM (tra cui il tuo TD) possiede il metodo onclick() (cioè la funzione che gestisce il rispettivo evento). A livello script questa funzione è definita intrinsecamente* in questo modo:
    codice:
    function onclick(event) {}
    *intrinsecamente significa che viene eseguito dello script predefinito, il quale si occupa di creare l'opportuna interfaccia per l'intera struttura degli elementi DOM. Non avviene nulla di magico e oscuro, ma questi processi avvengono in modo implicito.

    Ogni gestore di evento, per definizione, accetta come unico parametro un oggetto basato su Event, con cui è descritto l'evento verificato.

    Con quel codice quindi hai definito *SOLO* lo script da eseguire all'interno del gestore. Di per sé il gestore resta invariato, così come il suo parametro basato su Event.

    Questo passaggio puoi effettuarlo in modo analogo attraverso JavaScript, andando a definire proprio il gestore sulla "variabile" onclick (metodo del tuo oggetto TD).

    In sintesi hai questo:
    codice:
    TD.onclick = function(event){
       mostra(1);
    }
    Nota che la tua funzione mostra è "avvolta" dalla funzione definita come gestore.

    Ridefinire il gestore di un evento in questo modo diretto, è tuttavia una pratica sconsigliata in ambiti di programmazione complessa — ha la stessa valenza di definire l'evento direttamente come attributo del tag — principalmente perché in questo modo non puoi definire più listener per quello stesso evento.

    Il metodo addEventListener() invece permette una migliore organizzazione a livello funzionale, ma anche in questo caso valgono i principi finora valutati.

    Questo metodo non fa altro che applicare un "listener", cioè una funzione di callback che viene eseguita come gestore dell'evento.

    A questa funzione viene passato esattamente lo stesso tipo di parametro, cioè un oggetto Event, e non puoi passare direttamente altri parametri.

    Uno script come un altro, ne ho tanti altri a dimostrare che la funzione va invocata soltanto per nome e l'evento resta catturato nell'argomento aggiunto implementandola.
    Certo, esattamente come dici.

    La mia perplessità è perché non ci sia linearità funzionale nell'addEventListener(), che si aveva con gli eventi dichiarati nell'elemento del DOM, dato che invia al worker di turno l'evento ma soltanto quando gli pare lo rende gestibile; cioè, in quanto contesto di programmazione, la cosa mi stona.
    Questo può essere un "limite" del metodo addEventListener(), ma funziona in modo analogo anche con gli altri approcci, solo che in alcuni casi puoi andare ad aggirarlo in maniera più diretta, come nel tuo primo script dove, andando ad "assemblare" preventivamente il codice HTML, puoi ritrovare quella variabile dentro la tua funzione — ma questo accade proprio perché tutto il codice, assieme alla funzione, viene dato in pasto al browser solo dopo averlo assemblato.

    Ad ogni modo il tuo ultimo script può essere preso in considerazione per risolvere il passaggio della variabile, a patto di usare alcuni possibili stratagemmi, come ad esempio "l'incapsulamento"...
    una cosa di questo tipo:
    codice:
    for (i = 0; i < dvd.length; i++) {
      ((i)=>{
        dvd[i].addEventListener("click", function() {
          mostra(i);
        })
      })(i);
    }

    Ora, la spiegazione dettagliata la lascio per un'altra lezione ma a grandi linee avviene questo: usando una funzione autoeseguibile, posso passare un parametro che resterà in vita dentro lo scope di questa.

    Personalmente risolverei con un approccio differente...

    Nel tuo specifico caso andrei ad usare un attributo data in cui definire il valore che mi serve, quindi dentro la funzione vado a recuperarlo in modo relativo usando il this o un modo analogo.

    Magari potrebbe tornare più pratico definire una classe per "selezionare" quei TD in maniera più semplice senza doverli identificare singolarmente per il loro "id".

    Potrebbe anche essere più pratico applicare un unico evento sull'intera tabella, quindi usare la proprietà target (anziché this) per risalire all'elemento TD cliccato.

    Qui un esempio completo:
    codice:
    <!DOCTYPE HTML>
    <html lang="it">
       <head>
          <title>Esempio</title>
       <style>
          #tabella {
             border-spacing: 0;
          }
          #tabella td {
             border: 1px solid tan;
             padding: 5px 10px;
             cursor: pointer;
          }
          #tabella td:hover {
             background: silver;
          }
       </style>
       </head>
       <body>
          <table id="tabella" style="border: 1px solid #000"></table>
          <script>
    
             // Crea la tabella e le applica l'evento click
             function creaTabella(dvd){
                var html = '';
    
                for (let i = 0; i < dvd.length; i++) {
                   html += '<tr><td class="titolo_dvd" data-id-dvd="' + i + '">'
                         + dvd[i].getElementsByTagName("titolo")[0].childNodes[0].nodeValue
                         + '</td></tr>'
                   ;
                }
                const tabella = document.getElementById('tabella');
                tabella.innerHTML = html;
                tabella.addEventListener("click", tabellaOnClick);
             };
    
             // Listener del click sulla tabella
             function tabellaOnClick(e){
                const target = e.target;
    
                // Esco se non ho cliccato su un TD.titolo_dvd
                if (target.tagName !== 'TD' && !target.classList.contains('titolo_dvd')) return;
    
                // Recupero il valore data-id-dvd relativo a questo TD 
                const id = target.dataset.idDvd;
    
                // Visualizzo i dati
                mostra(id);
             }
    
             // Visualizza i dati del dvd relativo all'indice specificato
             function mostra(i){
                console.log('mostra', i);
             }
    
             // XML di esempio
             const xml =
             `<?xml version="1.0"?>
                <dvds>
                   <dvd><titolo>Titolo 0</titolo></dvd>
                   <dvd><titolo>Titolo 1</titolo></dvd>
                   <dvd><titolo>Titolo 2</titolo></dvd>
                   <dvd><titolo>Titolo 3</titolo></dvd>
                   <dvd><titolo>Titolo 4</titolo></dvd>
                   <dvd><titolo>Titolo 5</titolo></dvd>
                   <dvd><titolo>Titolo 6</titolo></dvd>
                   <dvd><titolo>Titolo 7</titolo></dvd>
                   <dvd><titolo>Titolo 8</titolo></dvd>
                </dvds>
             `;
             const dvd = (new DOMParser()).parseFromString(xml,'text/xml').getElementsByTagName('dvd');
    
             // Costruisco la tabella
             creaTabella(dvd);
          </script>
       </body>
    </html>
    ... perdonate la lungaggine

    Valuta tu se e come usare una tale soluzione. L'importante è che ti siano chiari quei concetti per poter comprendere cosa sta avvenendo dietro il codice.

    Spero di averti chiarito qualche dubbio, o più che altro di non aver confuso maggiormente le idee

    Fai sapere.
    Ultima modifica di KillerWorm; 25-06-2022 a 20:50
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  8. #8
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    Quote Originariamente inviata da KillerWorm Visualizza il messaggio


    Lui è mio amico

  9. #9
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,780
    Grazie KillerWorm!
    Bene che sei riuscito a risolvere

    Giusto per precisare, il termine "asincrono" non è riferito solo all'argomento AJAX e simili, ma al fatto che ogni evento in JavaScript si può innescare in un tempo non determinabile, per cui la funzione che viene richiamata per quel tale evento, avviene in modo asincrono rispetto allo script in cui questa è definita.

    E' comunque corretto il tuo discorso relativo alla variabile locale definita con let a livello di ciclo e quindi mantenuta valorizzata nel suo scope per ogni iterazione. Per cui la tua ultima soluzione può andare bene.

    ... in effetti tra i vari tuoi script non avevo fatto caso a quel let mancante nel ciclo che avrebbe risolto in modo semplice


    Quote Originariamente inviata da U235 Visualizza il messaggio
    Lui è mio amico
    eeeh, ma non dirlo a nessuno
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  10. #10
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    Quote Originariamente inviata da KillerWorm Visualizza il messaggio
    eeeh, ma non dirlo a nessuno

    Ma lui si vergogna di me


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 © 2026 vBulletin Solutions, Inc. All rights reserved.