Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 24
  1. #1

    Evento ignorato con la "nuova" sintassi

    Salve, ho una tabella, generata tramite un for di JavaScript, cui abbino al click in ogni cella, una funzione mostra(i) che carica dei contenuti da un file XML in un div apposito.
    Vorrei capire perché funziona così:
    codice:
    for (let i = 0; i < dvd.length; i++) {
          tabella += "<tr><td onclick='mostra(" + i + ")'>"; 
          tabella += dvd[i].getElementsByTagName("titolo")[0].childNodes[0].nodeValue;
          tabella += "</td></tr>";
    }
    
    function mostra(i) { ... }
    ma non così:
    codice:
    for (let i = 0; i < dvd.length; i++) {
            let indice = "film" + i;
            tabella += "<tr id='" + indice + "'><td>";
            tabella += dvd[i].getElementsByTagName("titolo")[0].childNodes[0].nodeValue;
            tabella += "</td></tr>";
            document.getElementById(indice).addEventListener("click", mostra);
    }
    
    function mostra(i) { ... }
    Va in errore il listener...
    Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')

  2. #2
    Credo che sia per il semplice fatto che ancora non esiste l'elemento tr relativo....
    Tu lo crei come stringa che assegni alla variabile tabella, ma non lo "inserisci" nel DOM e quando arriva alla riga del addEventListener non lo può trovare

  3. #3
    Ci ho pensato ma anche nel caso in cui funziona, la struttura della tabella è soltanto una stringa, non ancora aggiunta con innerHTML nella table.
    Quindi mi serve per forza un secondo for solo per gli event listener?

  4. #4
    Ah questo non lo so, nel senso....se puoi inserire le varie sezioni nel DOM dentro il ciclo "modificato", allora prima crei la parte DOM (la TR con relativa TD), poi la inserisci nel DOM e POI aggiungi l'evento.
    Se invece non puoi inserire nel DOM dentro quel ciclo, devi portare fuori l'aggiunta dell'evento

  5. #5
    Per semplificare ho separato le cose, prima creo la tabella con i titoli e assegno gli id:
    codice:
    for (let i = 0; i < dvd.length; i++) { // ciclo per caricare i titoli
            tabella += "<tr><td id='" + i + "'>";
            tabella += dvd[i].getElementsByTagName("titolo")[0].childNodes[0].nodeValue;
            tabella += "</td></tr>";
    }
    Poi inserisco la tabella nel table con id="tabella":
    codice:
    document.getElementById("tabella").innerHTML = tabella;
    Quindi assegno gli eventi a tutti i td tramite i loro id progressivi:
    codice:
    for (let i = 0; i < dvd.length; i++) {
            document.getElementById(i).addEventListener("click", mostra);
    }
    Risultato: mostra(i) ignora i click su tutti i td e va in errore sull'ultimo:
    Uncaught TypeError: Cannot read properties of undefined (reading 'getElementsByTagName')
    codice:
    function mostra(i) {
            let j = Number(i); // conversione fatta caso mai prendesse i come stringa in dvd[]
            document.getElementById("mostraDVD").innerHTML = "Titolo: " +
            dvd[j].getElementsByTagName("titolo")[0].childNodes[0].nodeValue + "<br />Regista: " +
            dvd[j].getElementsByTagName("regista")[0].childNodes[0].nodeValue + "<br />Genere: " +
            dvd[j].getElementsByTagName("genere")[0].childNodes[0].nodeValue + "<br />Anno: " +
            dvd[j].getElementsByTagName("anno")[0].childNodes[0].nodeValue;
    }
    dvd è il responseXML sui tag DVD, correttamente funzionante per codici simili ma senza la tabella interattiva al click (DVD navigabili con button o tabella caricata senza eventi annessi...).

  6. #6
    codice:
    for (let i = 0; i < dvd.length; i++) { // ciclo per caricare i titoli
            tabella = "<tr><td id='" + i + "'>";
            tabella += dvd[i].getElementsByTagName("titolo")[0].childNodes[0].nodeValue;
            tabella += "</td></tr>";
            document.getElementById("tabella").insertAdjacentHTML("beforeend", tabella);
            document.getElementById(i).addEventListener("click", mostra);
    }
    Non ho verificato nè testato ma direi che dovrebbe andare bene

  7. #7
    Utente di HTML.it L'avatar di ninja72
    Registrato dal
    May 2020
    residenza
    -
    Messaggi
    319
    Vedi se questo esempio ti può essere d'aiuto, ciao.

    codice:
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    
    <body>
        <table id="mytable"></table>
    
        <script>
            const mytable = document.getElementById('mytable')
            let tabella = ''
    
            //// con innerHTML
            // for (let i = 0; i < 10; i++) {
            //     tabella += `<tr class='film'><td>${i}</td></tr>`
            //     mytable.innerHTML = tabella
            // }
    
            //// con createElement
            for (let i = 0; i < 10; i++) {
                const tr = document.createElement('tr')
                const td =  document.createElement('td')
                td.textContent = i
                tr.appendChild(td)
                tr.classList.add('film')
                mytable.appendChild(tr)
            }
    
            function mostra(e) {
                let j = e.target.parentElement.rowIndex
                console.log(j)
            }
    
            const myfilms = document.querySelectorAll('table#mytable tr.film')
    
            myfilms.forEach(el => {
                el.addEventListener("click", mostra)
            })
    
        </script>
    </body>
    
    </html>

  8. #8
    Moderatore di Javascript L'avatar di ciro78
    Registrato dal
    Sep 2000
    residenza
    Napoli
    Messaggi
    8,514
    scusa ma da quello che dici l'evento sembra funzionare. quello che non ti torna è dvd che è diverso.
    Ciro Marotta - Programmatore JAVA - PHP
    Preferisco un fallimento alle mie condizioni che un successo alle condizioni altrui.


  9. #9
    Quote Originariamente inviata da Dascos Visualizza il messaggio
    codice:
    for (let i = 0; i < dvd.length; i++) { // ciclo per caricare i titoli
            tabella = "<tr><td id='" + i + "'>";
            tabella += dvd[i].getElementsByTagName("titolo")[0].childNodes[0].nodeValue;
            tabella += "</td></tr>";
            document.getElementById("tabella").insertAdjacentHTML("beforeend", tabella);
            document.getElementById(i).addEventListener("click", mostra);
    }
    Non ho verificato nè testato ma direi che dovrebbe andare bene
    Purtroppo l'unico effetto che ottengo è che va in errore su tutti i td, non soltanto sull'ultimo ignorando i click sugli altri.

  10. #10
    Quote Originariamente inviata da ciro78 Visualizza il messaggio
    scusa ma da quello che dici l'evento sembra funzionare. quello che non ti torna è dvd che è diverso.
    Anche a me l'evento "sembra" funzionare guardando il codice, invece non vuole saperne di caricare i dati dell'XML nel div dedicato.
    Funziona tutto se uso onclick() nel td ma devo risolverlo con addEventListener(), e non comprendo l'errore nel leggere il tag nell'XML
    getElementsByTagName
    dato che in una versione con button per spostarsi da un film all'altro funziona bene.

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.