sangmister sangmister - 2 months ago 19
Javascript Question

getElementsByClassName error within a div

I have a page with multiple div's containing html5 video players. Basically something like this

<div class="panel">
<video class="player"><source src="video1.mp4" type="video/mp4" /></video>
</div>
<div class="panel">
<video class="player"><source src="video2.mp4" type="video/mp4" /></video>
</div>
...


Now I want to iterate through all elements with the class "panel" and pause all videoplayers. So I'm trying this in JavaScript:

var panels = document.getElementsByClassName("panel");
for (i = 0; i < panels.length; i++) {
var video = panels[i].getElementsByClassName("player");
video.pause();
}


What I get is this error message:

Uncaught TypeError: panels[i].getElementByClassName is not a function


Is there anybody who can help me fix this?

Thanks a lot in advance!!

Answer

Your question has a mispelling. It refers to:

document.getElemtsByClassName(...)

which should be:

document.getElementsByClassName(...)

Assuming that is just a typo in your question (since you don't report the error that would cause), then:


This line of code gets an HTMLCollection, not an individual DOM element:

var video = panels[i].getElementsByClassName("player");

So, you can't do:

 video.pause();

because video in that above line of code is an HTMLCollection, not a DOM element and an HTMLCollection doesn't have a .pause() method. To get a DOM element from the HTMLCollection, you have to reach into it with an property index to get an individual DOM element:

 video[0].pause();

Or, you can iterate the whole HTMLCollection to operate on all the DOM elements in the HTML collection. This would be getting the first player object in each div (see the [0]):

var panels = document.getElementsByClassName("panel");
for (i = 0; i < panels.length; i++) {
  var video = panels[i].getElementsByClassName("player")[0];
  video.pause();
}

Or, if you wanted all player objects using this technique, you would need to use two for loops:

var panels = document.getElementsByClassName("panel");
for (var i = 0; i < panels.length; i++) {
  var videos = panels[i].getElementsByClassName("player");
  for (var j = 0; j < videos.length; j++) {
      videos[j].pause();
  }
}

You also may just want to use document.querySelectorAll() and do this all in one query and one iteration:

var videos = document.querySelectorAll(".panel .player");
for (var i = 0; i < videos.length; i++) {
    videos[i].pause();
}

Also, given your HTML, it's not entirely clear why you first query .panel elements. If you have no other .player objects that you're trying to avoid, you can just get the player objects directly in a simpler query:

var videos = document.querySelectorAll(".player");
for (var i = 0; i < videos.length; i++) {
    videos[i].pause();
}

And, though you didn't ask about using jQuery, it's often useful for DOM queries, iterations and manipulations:

$(".panel .player").each(function() {
    this.pause();
});