简体   繁体   中英

How do I attach eventlisteners to an array of html elements and parse data attributes as arguments in javascript?

I am building a custom audio player in Javascript, but I have trouble attaching an event listener to each song in the list. When I click on a track in the playlist, I want to parse a data attribute through a function called selectTrack(x) to tell the player which song to play. However, I keep getting an error saying that this function is not defined.

This is is the part I have trouble with:

// attach event listener and get data value from div 
var myListener = document.getElementsByClassName("trackListRow");
for (var i=0; i < myListener.length; i++)
{
  myListener[i].getAttribute("data-track-index");
  mylistener[i].addEventListener("click", function(){

    selectTrack(datavalue);

  });
}

The full code is posted below.

 var trackListContainer, playPrevBtn, playPauseBtn, PlayNextBtn; var trackRow, songArray; songArray = ["Aminaiyoamoore", "adg3com_chuckedknuckles" ]; // create track list - append to container var i; for (i = 0; i < songArray.length; i++) { trackRow = document.createElement("div"); trackRow.textContent = songArray[i]; trackRow.className = "trackListRow"; // set data attribute to array index number for event handling trackRow.setAttribute("data-track-index", songArray.indexOf(songArray[i])); trackListContainer = document.getElementById("trackListContainer"); trackListContainer.appendChild(trackRow); } // Problems here // attach event listener and get data value from div var myListener = document.getElementsByClassName("trackListRow"); for (var i=0; i < myListener.length; i++) { myListener[i].getAttribute("data-track-index"); mylistener[i].addEventListener("click", function(){ selectTrack(datavalue); }); } var playPrevBtn, playPauseBtn, playNextBtn; playPrevBtn = document.getElementById("playPrevBtn"); playPauseBtn = document.getElementById("playPauseBtn"); playNextBtn = document.getElementById("playNextBtn"); function initBeatPlayer() { // var dir = "audio/"; var dir = "http://www.puntlandtvradio.net/placeholders/audio/" var ext = ".mp3"; playlist_array_index = 0; audio = new Audio(); playPauseBtn.addEventListener("click", playPause); playPrevBtn.addEventListener("click", seekBackward); playNextBtn.addEventListener("click", seekForward); audio.addEventListener("ended", function() { switchTrack() }); // functions function selectTrack(datavalue){ playlist_array_index = datavalue audio.src = dir + songArray[playlist_array_index] + ext; audio.play(); } function playPause() { if (audio.paused) { audio.play(); document.getElementById("playPauseBtn").textContent = "PAUSE"; } else { audio.pause() document.getElementById("playPauseBtn").textContent = "PLAY" } } function seekBackward() { if (playlist_array_index <= 0) { playlist_array_index = 0; audio.src = dir + songArray[playlist_array_index] + ext; audio.pause(); audio.currentTime = 0; audio.play(); } else { playlist_array_index--; audio.src = dir + songArray[playlist_array_index] + ext; audio.play(); } } function seekForward() { if (playlist_array_index == (songArray.length - 1)) { playlist_array_index = 0; } else { playlist_array_index++; audio.src = dir + songArray[playlist_array_index] + ext; audio.play(); } } //end functions } window.addEventListener("load", initBeatPlayer); 
 #container{width: 320px; margin: auto; overflow: hidden;} #controls {} #playPrevBtn, #playPauseBtn, #playNextBtn{ font-size: 25px; margin: 5px;} .trackListRow {font-size: 20px; background-color: aliceblue; color: black; padding: 10px; margin: 5px;} .trackListRow:hover {background: brown; color: white; } 
 <!--player control buttions --> <div id="container"> <div id="trackListContainer"> </div> <div id="controls"> <button id="playPrevBtn"> << </button> <button id="playPauseBtn">PAUSE</button> <button id="playNextBtn">>></button> </div> <div> music by puntlandtvradio.net - for educational purposes </div> </div> 

Couple of things:

  1. The second line inside the for loop: mylistener should be myListener (capitalised L )
  2. The datavalue in the event listener is undefined, declare it first.
  3. Like the comments pointed out, selectTrack is inside initBeatPlayer , hence not available publicly. However, given that selectTrack needs to refer to other vars inside initBeatPlayer as well, it's probably better to move your handler-binding work inside initBeatPlayer as well.

Here is a "working" jsFiddle, you still need to clean up other parts beside that snippet: https://jsfiddle.net/bosjuLmo/1/

You need to declare all your variables, listeners at the top of the script; this way you know every element is defined when functions need them. Same thing for functions, better write them before the calls.

Keep in mind that variables declared with 'var' inside a function, are representative in a local scope. 'var dir' in a global scope is not the same as 'var dir' inside a function, JS will treat them as separate things.

Hope this helps, it's working OK:

var trackListContainer, playPrevBtn, playPauseBtn, PlayNextBtn;
var trackRow, songArray;
songArray = ["Aminaiyoamoore", "adg3com_chuckedknuckles" ];
var myListener = document.getElementById("trackListContainer");
var dir='';
var ext='';

var playPrevBtn, playPauseBtn, playNextBtn;
playPrevBtn = document.getElementById("playPrevBtn");
playPauseBtn = document.getElementById("playPauseBtn");
playNextBtn = document.getElementById("playNextBtn");

window.addEventListener("load", initBeatPlayer);

// functions 


  function selectTrack(datavalue){

    playlist_array_index = datavalue
    audio.src = dir + songArray[playlist_array_index] + ext;          
            audio.play();

  }






    function playPause() {
        if (audio.paused) {
            audio.play();
            document.getElementById("playPauseBtn").textContent = "PAUSE";
        } else {
            audio.pause()
            document.getElementById("playPauseBtn").textContent = "PLAY"
        }
    }


    function seekBackward() {
        if (playlist_array_index <= 0) {

            playlist_array_index = 0;
            audio.src = dir + songArray[playlist_array_index] + ext;
            audio.pause();
            audio.currentTime = 0;
            audio.play();
        } else {

            playlist_array_index--;
            audio.src = dir + songArray[playlist_array_index] + ext;
            audio.play();
        }
    }

    function seekForward() {

        if (playlist_array_index == (songArray.length - 1)) {
            playlist_array_index = 0;

        } else {

            playlist_array_index++;
            audio.src = dir + songArray[playlist_array_index] + ext;          
            audio.play();

        }

    }

function initBeatPlayer() {
   // var dir = "audio/";
   dir =  "http://www.puntlandtvradio.net/placeholders/audio/"

    ext = ".mp3";
    playlist_array_index = 0;
    audio = new Audio();


    playPauseBtn.addEventListener("click", playPause);
    playPrevBtn.addEventListener("click", seekBackward);
    playNextBtn.addEventListener("click", seekForward);
    audio.addEventListener("ended", function() {
        switchTrack()
    });
}

//end functions

// create track list - append to container

for (var i = 0; i < songArray.length; i++) {
    trackRow = document.createElement("div");
    trackRow.textContent = songArray[i];
    trackRow.className = "trackListRow";
    // set data attribute to array index number for event handling
    trackRow.setAttribute("data-track-index", songArray.indexOf(songArray[i]));

    trackListContainer = document.getElementById("trackListContainer");
    trackListContainer.appendChild(trackRow);

}  

       //  Problems here
// attach event listener and get data value from div 

for (var i=0; i < myListener.length; i++){
  myListener[i].getAttribute("data-track-index");
  mylistener[i].addEventListener("click", function(){

    selectTrack(datavalue);

  });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM