dan2004 dan2004 - 2 months ago 7
Javascript Question

Playing next video by calling a function that needs the event passed to it

The question of how can JavaScript call the next video has been asked as I have thoroughly researched this topic before posting. However, in the situation that I will describe, a video is running after an onclick event calls the function: function(e) and I need to be able to call the next video by calling the function(e) again once the code detects an ended event by using the addEventListener method.

I have posted all my code below. In addition I have added comments to illustrate what I “think” is happening. I am brand new to JavaScript and have recently retired, so I have had time to research the Internet to try and piece together what is taking place. Please feel free to clarify my commented code as I would appreciate being set straight on what I have wriiten.

I have also made an attempt to put the code on jsfiddle

https://jsfiddle.net/dan2004/tuouh36d/

but it only seems to function in Chrome.

My main question to everyone is in regard to the statement:

document.getElementById('videoPlayer').addEventListener('ended',handler,false);

If I call a function outside of the function, I can issue a message via an alert, but if I call the function that I am in (handler(e)) I cannot get the next video to run. Somehow I need to be able to call the handler(e) function and send it the next onclick event.

Thanks for any help.




var video_playlist, links, i, videotarget, filename, video, source;

// Gets the video object from <div id="player"> in the HTML
video_playlist = document.getElementById("player");

// "links" is an array which contains all the <a href> tags in the <div id="playlist">.
// This div is located within <div id="player"> and contains a clickable playlist.
links = video_playlist.getElementsByTagName('a');

// This "for loop" scrolls through the links array of <a href> attributes and
// assigns an "onclick = handler" event to each one.
for (i=0; i<links.length; i++) {
links[i].onclick = handler;
};


// e is an [object MouseEvent]
function handler(e) {


// The handler function receives the full path to the mp4 file when it is clicked on in the playlist.
// The "preventDefault" method stops the function from following that path.
// This is so the data in the path may be parsed and manipulated below
e.preventDefault();

// videotarget grabs the href attribute of the item clicked on
// in the "playlist". This is the full path to the video file.
videotarget = this.getAttribute("href");

// Through the use of substr, filename grabs that part of the href which
// does not include the extension.
filename = videotarget.substr(0, videotarget.lastIndexOf('.')) || videotarget;

// The variable "video" contains the video object. This is obtained by using document.querySelector().
// This document method uses the css id class, #player, and grabs the [object HTML VideoElement].
// The [object HTML VideoElement] resides in <div id="player">
video = document.querySelector("#player video");

//Removes the poster attribute in the video tag
video.removeAttribute("poster");

// The source variable is used to hold an array of all the source tags in the
// [object HTML VideoElement] from <div id="player">.
source = document.querySelectorAll("#player video source");

// Using the substring extracted from the user's click choice in <div id="playlist">
// the three file types for browsers to choose from are concatenated to the string.
// These thre source files are then stored under the video object located in <div id="player">.
source[0].src = filename + ".mp4";
source[1].src = filename + ".webm";
source[2].src = filename + ".ogv";

// The video object will load the appropriate source[].src file then play it
video.load();
video.play();

// When the video ends the following statement will call the function test()
// which will then broadcast the alert message "Video Ended"
document.getElementById('videoPlayer').addEventListener('ended',test,false);

// This statement will not call the handler function in order to play the next video selection.
// document.getElementById('videoPlayer').addEventListener('ended',handler,false);

}; // function handler(e)

function test(){
alert("Video Ended");
};

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Video Playlist Tutorial</title>
<style>
body {font-family:Arial, Helvetica, sans-serif;background:#fff}
.center {text-align:center;width:640px;margin:0 auto;}
#player {background:#000; padding:10px;width:640px;margin:0 auto;border-radius:10px;}
#player video {width:640px;}
#playlist {background:#333;list-style:none;padding:0;margin:0; width:640px;}
#playlist h1 {font: 24px Arial, Helvetica, sans-serif; color:#FFF; font-weight:bold;padding:5px 2px;margin:0;}
#playlist a {color:#eeeedd;background:#333;padding:10px 5px;display:block;text-decoration:none;border-bottom:1px solid #222;}
#playlist a:hover {text-decoration:none; background:#999;color:#000}
</style>
</head>
<body>
<div id="player"> <!-- Assign id to video tag for ended event and to call handler to play next video -->
<video id="videoPlayer" controls="controls" width="640" height="360" preload="auto" autoplay >
<source src="1.mp4" type="video/mp4" />
<source src="1.webm" type="video/webm" />
<source src="1.ogv" type="video/ogg" />
</video>
<div id="playlist">
<h1>Videos</h1>
<a href="http://www.w3schools.com/html/movie.mp4">Bear</a> <br>
<a href="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4">Buck Bunny</a>
</div>
</div>

<script>
</script>

</body>
</html>




Answer

Seeing as your handler() function relies on this being the clicked element, you can't just call that function, you'd have to also set the this-value to the next anchor etc. and trigger the event in a way that makes it look like it was triggered by the actual element.

An easier way to do this, would be to just decouple the playing logic, get the next element, and play the video

var video_playlist = document.getElementById("player");
var links = video_playlist.getElementsByTagName('a');

for (var i = 0; i < links.length; i++) {
    (function(j) {
        links[j].addEventListener('click', function(e) {
            handler.apply(this, [e, j])
        });
    })(i);
};

function handler(e, index) {
    e.preventDefault();
    var videotarget = this.getAttribute("href");
    
    play(videotarget, index).addEventListener('ended', function() {
        index = (++index) >= links.length ? 0 : index;
        play(links[index].getAttribute("href"), index);
    });
};

function play(videotarget) {
    var filename = videotarget.substr(0, videotarget.lastIndexOf('.')) || videotarget;
    var video = document.querySelector("#player video");
    var source = document.querySelectorAll("#player video source");
    
    video.removeAttribute("poster");
    source[0].src = filename + ".mp4";
    source[1].src = filename + ".webm";
    source[2].src = filename + ".ogv";
    video.load();
    video.play();
    return video;
};
<div id="player">
    <!-- Assign id to video tag for ended event and to call handler to play next video -->
    <video id="videoPlayer" controls="controls" width="640" height="360" preload="auto" autoplay>
        <source src="1.mp4" type="video/mp4" />
        <source src="1.webm" type="video/webm" />
        <source src="1.ogv" type="video/ogg" />
    </video>
    <div id="playlist">
        <h1>Videos</h1>
        <a href="http://www.w3schools.com/html/movie.mp4">Bear</a>
        <a href="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4">Buck Bunny</a>
    </div>
</div>

Comments