Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

What am I missing for this to work properly?

Hi guys,

I'm trying to get the text under my video to highlight as the video plays. Right now, when I press play, the entire chunk of text highlights. What am I doing wrong?

Thanks,

<div id="subtitles">

    <p>

    <span id="l1" class="line" data-end="00:00:04.130" data-start="00:00:00.240">Now that we've looked at the architecture of the internet, let's see how you might</span>

    <span id="l2" class="line" data-end="00:00:07.535" data-start="00:00:04.130">connect your personal devices to the internet inside your house.</span>

    <span id="l3" class="line" data-end="00:00:11.270" data-start="00:00:07.535">Well there are many ways to connect to the internet, and</span>

    <span id="l4" class="line" data-end="00:00:13.960" data-start="00:00:11.270">most often people connect wirelessly.</span>

    <span id="l5" class="line" data-end="00:00:17.940" data-start="00:00:13.960">Let's look at an example of how you can connect to the internet.</span>

    </p>
.current {
   background-color: yellow;
}
var lines = document.getElementById("subtitles").getElementsByTagName("span");
var now = video.currentTime;

// Update the progress bar as the video plays
video.addEventListener('timeupdate', function() {
// highlight text as video plays
  for (var i = 0, l = lines.length; i < l; i++) {
    if (now >= +lines[i].getAttribute("start") && now <= +lines[i].getAttribute("end")) {
      lines[i].className = "current";
    } else {
      lines[i].className = "";
    }
  }
});

I don't know if it will solve your problem, but you for loop should have a semicolon after the var i = 0 instead of a comma

Unfortunately, that didn't help

Nathan,

Adding in another semicolon would probably lead to an error since the for statement already has the required 2 semicolons. The comma in this case is acting as the comma operator and it's ok to do something like that.

Gina,

I'll leave an answer and try to help out since you posted some code, but in general, non-techdegree students don't have access to the projects so we don't know anything about them other than what you post in your question.

Check out this post that Treasure Porth replied to: https://teamtreehouse.com/community/how-do-i-get-transcript-to-highlight-along-with-html-video-when-it-plays

You might get better results with the slack channel and I think you're supposed to have a mentor too.

Thanks, Jason! I'll try the Slack channel.

3 Answers

Hi Gina,

Have you tried to do any troubleshooting to see what might be going on?

You can inspect the html using your browser's dev tools to see what's going on with the "current" class.

Based on your description it looks like all of the spans are getting the current class which would mean your if condition is always true.

You can work backwards from that to see why it might be always true.

There's a few potential problems that I'm seeing.

You don't seem to be updating the now variable. You're only assigning the currentTime property once and at that point it might be zero if the video isn't playing yet. I would log that value to the console to see what it is.

You probably should be getting the currentTime inside your event handler. That way the now variable has the actual current time and you can properly compare it to the start and end times for each span.

Another issue is with your getAttribute calls. I believe you need the full attribute name there. See the notes on this page https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute for what it returns when the attribute is not found.

It will return null on modern browsers and when you use the unary plus operator on null it will return 0.

In your if condition you would be doing +null and that will become 0.

So I think your if condition might be getting evaluated as

 if (0 >= 0 && 0 <= 0) {

And that could be one explanation for why it's always true.

Also, you will have another problem once you fix the attribute names. I don't think your time markers will get converted how you hope.

See the following console output:

+"00:00:04.130"
NaN

The time markers can't be converted into numbers because of the colons.

The currentTime property is returned in seconds so you need to get your attribute values into seconds one way or another.

You could store the attribute values as seconds if you're not required to store them as time markers. Or you could write a function that will accept a time marker string and return the total numbers of seconds.

So if you pass in the string "01:00:00.000" it should return the integer 3600 since 1 hour is 3600 seconds.

Once everything is in seconds you should be able to do accurate comparisons in your if condition.

You could try and take out the 'l = lines.length' and just write the for loop like ' for(var i = 0; i < lines.length; i++); '

Thanks for the suggestion but that didn't work either.

Thanks Jason,

See below for my final code. The issue had to do with my markup, like you mentioned. I was just copying and pasting numbers from my vtt file, which was not the way to go. Once I formatted the string "01:00:00:000" to "10.00" everything worked. Thanks for your help!

<span id="l1" class="line" data-end="04.13" data-start="00.24">Now that we've looked at the architecture of the internet, let's see how you might</span>

var lines = document.getElementById("subtitles").getElementsByTagName("span"); var now = video.currentTime;

    // Update the time as the video plays
video.addEventListener("timeupdate", function() {
    // loop through each span
for (var i = 0; i < lines.length; i++) {

    var now = video.currentTime;
    var start = lines[i].getAttribute("data-start");
    var end = lines[i].getAttribute("data-end");    

      if (now >= start && now <= end) {
        lines[i].className = "current";
      } else {
        lines[i].className = "";
      }
    }
});