1

So I'm working with a JW Player and everything is working great except for one piece of functionality I'm working on. When I run the code I get a console error: Uncaught TypeError: upTop.addEventListener is not a function

Here is the code:

                var upTop = document.getElementsByClassName('playlist-item');

                upTop.addEventListener('click', function() {
                jwplayer.setup({autostart: true, floating: {dismissable: true}});
                       window.scrollTo(0, 0);
                });

Is there some kind of syntax error I'm missing here?

Taplar
  • 24,788
  • 4
  • 22
  • 35
MikeL5799
  • 445
  • 1
  • 9
  • 27

4 Answers4

5

Calling getElementsByClassName works differently from getElementById. Multiple elements can have the same class name so what is returned is an array. For example, if you want the first item returned because you know there is only one element with the class then

var upTop = document.getElementsByClassName('playlist-item')[0];

would suffice. Otherwise, you can loop through all items in upTop and add the event listener to all of them. In pure JS:

for (var i=0; i < upTop.length;i++) {
 upTop[i].addEventListener('click', function() {
    wplayer.setup({autostart: true, floating: {dismissable: true}});
    window.scrollTo(0, 0);
 });
}
Eli
  • 81
  • 4
3

UpTop is a list of elements rather than the element it self.

If you are trying to apply it to one element you can use upTop[0].addEventListener

Or if its multiple loop over them and bind them individually

Sam James
  • 269
  • 1
  • 6
1

document.getElementsByClassName returns an HTMLCollection and HTMLCollection doesnot have property addEventListener

For Only First Element

var upTop = document.querySelector('.playlist-item');

Using for loop

If you want to add event listener on all the elements then use for loop.

var upTop = document.getElementsByClassName('playlist-item');
for(let i = 0;i<upTop.length;i++){
    upTop[i].addEventListener('click', function() {
       ...
    });
}

Using forEach

Or you can convert it into array and use forEach()

var upTop = [...document.getElementsByClassName('playlist-item')];
upTop.forEach(a => a.addEventListener(click,() => ...))

Using jQuery

$('.playlist-item').click(function(){
   ...
})
Maheer Ali
  • 35,834
  • 5
  • 42
  • 73
1

You may be better off refactoring your code to take advantage of event delegation. Essentially the technique is used to delegate event handling to a single parent container - this way we don't have to add an event listener on each and every element that we want to register a click handler on.

Here's an example:

//A parent container for event delegation purposes
var containerEl = document.querySelector('#playlist-items-container');

//Add the event handler to the parent container and analyze the target when an element is clicked on
containerEl.addEventListener('click', e => {
  //Check if a //playlist-item was clicked
  if (e.target.className.indexOf('playlist-item') > -1) {
    console.log(`${e.target.textContent} was clicked`);
    //Do jwplayer.setup(...);
    //Do window.scrollTo(...);
  }
});
<div id="playlist-items-container">
  <div class="playlist-item">Playlist item 1</div>
  <div class="playlist-item">Playlist item 2</div>
  <div class="playlist-item">Playlist item 3</div>
  <div class="playlist-item">Playlist item 4</div>
</div>
Tom O.
  • 5,730
  • 2
  • 21
  • 35