无法将侦听器添加到另一个按钮创建的按钮

时间:2019-10-14 08:06:45

标签: javascript html css

首先,我是编程的新手。

我有一个按钮(Canciones),它在空的div中(在右侧)创建了多个按钮,但是我无法向其中添加EventListeners,因此无法正常工作。我认为也许监听器处于打开状态,但是由于"can't read property of undefined",它们无法工作。我不知道发生了什么,但是我浪费了很多时间试图自己解决。

let canciones = [
    {
        nombre: "Heroes",
        portada: "img/album/davidBowieHeroes.jpg",
        audio: "music/davidBowieHeroes.mp3",
        autor: "David Bowie",
        album: "Heroes",
        genero: "Rock Pop"
    },
    {
        nombre: "Detroit Rock City",
        portada: "img/album/kissDestroyer.jpg",
        audio: "music/kissDetroitRockCity.mp3",
        autor: "Kiss",
        album: "Destroyer",
        genero: "Rock"
    },
    {
        nombre: "Bycicle Race",
        portada: "img/album/queenJazz.jpg",
        audio: "music/queenBycicleRace.mp3",
        autor: "Queen",
        album: "Jazz",
        genero: "Rock"
    },
    {
        nombre: "Livin' On A Prayer",
        portada: "img/album/bonJoviSlipperyWhenWet.jpg",
        audio: "music/bonJoviLivin'OnAPrayer.mp3",
        autor: "Bon Jovi",
        album: "Slippery When Wet",
        genero: "Rock"
    },
    {
        nombre: "I'm Just a Singer in a Rock and Roll Band",
        portada: "img/album/theMoodyBluesSeventhSojourn.jpg",
        audio: "music/theMoodyBluesI'mJustASingerInRockAndRollBand.mp3",
        autor: "The Moody Blues",
        album: "Seventh Sojourn",
        genero: "Rock"
    },
    {
        nombre: "London Calling",
        portada: "img/album/theClashLondonCalling",
        audio: "music/theClashLondonCalling.mp3",
        autor: "The Clash",
        album: "London Calling",
        genero: "Punk"
    },
    {
        nombre: "Master Of Puppets",
        portada: "img/album/metallicaMasterOfPuppets.jpg",
        audio: "music/metallicaMasterOfPuppets.mp3",
        autor: "Metallica",
        album: "Master Of Puppets",
        genero: "Heavy Metal"
    },
    {
        nombre: "Hangar 18",
        portada: "img/album/megadethRustInPeace.jpg",
        audio: "music/megadethHangar18.mp3",
        autor: "Megadeth",
        album: "Rust In Peace",
        genero: "Heavy Metal"
    },
    {
        nombre: "Some Might Say",
        portada: "img/album/oasisMorningGlory.jpg",
        audio: "music/oasisSomeMightSay.mp3",
        autor: "Oasis",
        album: "Morning Glory",
        genero: "Rock"
    },
    {
        nombre: "God Only Knows",
        portada: "img/album/theBeachBoysPetSounds.jpg",
        audio: "music/theBeachBoysGodOnlyKnows.mp3",
        autor: "The Beach Boys",
        album: "Pet Sounds",
        genero: "Rock"
    }
]

const nombreCancion = document.getElementById("nombreCancion");
const imgAlbum = document.getElementById("imgAlbum");
const cancion = document.getElementById("cancion");
const nombreAutor = document.getElementById("nombreAutor");
const albumCancion = document.getElementById("albumCancion");
const genero = document.getElementById("genero");
const cancionesA = document.getElementById("canciones");

var i = 0;

function boton1() {
    cancionesA.innerHTML = "";
    for (i = 0; i < canciones.length; i++) {
        let boton = document.createElement("button");   
        boton.innerText = canciones[i].nombre; 
        boton.setAttribute("class", "cancion");
        boton.addEventListener('click', function(){
            cambiarCancion(canciones);
        });
        cancionesA.appendChild(boton);
    }
}

function cambiarCancion() { 
        nombreCancion.innerText = canciones[i].nombre;
        imgAlbum.src = canciones[i].portada;
        cancion.src = canciones[i].audio;
        nombreAutor.innerText = canciones[i].autor;
        albumCancion.innerText = canciones[i].album;
        genero.innerText = canciones[i].genero;
}

监听器不起作用。

1 个答案:

答案 0 :(得分:2)

也许最简单的解决方案是在父元素(cancionesA)中添加一个事件监听器,并在子元素冒起DOM时捕获子元素的点击。这称为event delegation。在按钮循环中,您可以为每个按钮分配一个ID,然后您可以使用该ID来标识被单击的按钮。

let canciones = [{"nombre":"Heroes","portada":"img/album/davidBowieHeroes.jpg","audio":"music/davidBowieHeroes.mp3","autor":"David Bowie","album":"Heroes","genero":"Rock Pop"},{"nombre":"Detroit Rock City","portada":"img/album/kissDestroyer.jpg","audio":"music/kissDetroitRockCity.mp3","autor":"Kiss","album":"Destroyer","genero":"Rock"},{"nombre":"Bycicle Race","portada":"img/album/queenJazz.jpg","audio":"music/queenBycicleRace.mp3","autor":"Queen","album":"Jazz","genero":"Rock"},{"nombre":"Livin' On A Prayer","portada":"img/album/bonJoviSlipperyWhenWet.jpg","audio":"music/bonJoviLivin'OnAPrayer.mp3","autor":"Bon Jovi","album":"Slippery When Wet","genero":"Rock"},{"nombre":"I'm Just a Singer in a Rock and Roll Band","portada":"img/album/theMoodyBluesSeventhSojourn.jpg","audio":"music/theMoodyBluesI'mJustASingerInRockAndRollBand.mp3","autor":"The Moody Blues","album":"Seventh Sojourn","genero":"Rock"},{"nombre":"London Calling","portada":"img/album/theClashLondonCalling","audio":"music/theClashLondonCalling.mp3","autor":"The Clash","album":"London Calling","genero":"Punk"},{"nombre":"Master Of Puppets","portada":"img/album/metallicaMasterOfPuppets.jpg","audio":"music/metallicaMasterOfPuppets.mp3","autor":"Metallica","album":"Master Of Puppets","genero":"Heavy Metal"},{"nombre":"Hangar 18","portada":"img/album/megadethRustInPeace.jpg","audio":"music/megadethHangar18.mp3","autor":"Megadeth","album":"Rust In Peace","genero":"Heavy Metal"},{"nombre":"Some Might Say","portada":"img/album/oasisMorningGlory.jpg","audio":"music/oasisSomeMightSay.mp3","autor":"Oasis","album":"Morning Glory","genero":"Rock"},{"nombre":"God Only Knows","portada":"img/album/theBeachBoysPetSounds.jpg","audio":"music/theBeachBoysGodOnlyKnows.mp3","autor":"The Beach Boys","album":"Pet Sounds","genero":"Rock"}];

const nombreCancion = document.getElementById("nombreCancion");
const cancionesA = document.getElementById("canciones");

function boton1() {

  // Create a document fragment to save on DOM hits
  const frag = document.createDocumentFragment();

  // For each button
  canciones.forEach((current, index) => {
    let boton = document.createElement("button");   
    boton.innerText = current.nombre;

    // Add the index as a data attribute
    boton.dataset.id = index;
    boton.setAttribute("class", "cancion");

    // Append the button the fragment
    frag.appendChild(boton);
  });

  // Finally append the fragment to the parent element
  cancionesA.appendChild(frag)
}

// Add one event listener to the parent element
cancionesA.addEventListener('click', cambiarCancion, false);

function cambiarCancion(e) {

  // Destructure the id from the target element (the
  // button that was clicked)
  const { target: { dataset: { id } } } = e;
  nombreCancion.innerText = canciones[id].nombre;
}

boton1();
<div id="canciones"></div>
<div id="nombreCancion"></div>

进一步阅读