Search code examples
javascriptjqueryarraysjquery-selectorshtml5-video

Alternating multiple video lists in html5 stored as javascript arrays


I have designed an i-phone-like screen on a web browser where I am testing this application I am in the process of building. It works great up until the point where I want to call out another set of videos.

What works

The application is structured so that when the user sees the screen she is directed to a channel that has a vertical video. The buttons on the top left and top right advance to the next and the previous video.

    <div id="topVid" class="videoContainer">
        <div class="topHorizontalButtonRow">
          <a href="#" class="buttonLeftTriangleBlue" onClick="return Vids.prev();"></a>
          <a href="#" class="buttonRightTriangleBlue" id="nextButtonTop" onClick="return Vids.next();"></a>
         </div>

        <video class="topVid" loop onclick="this.paused? this.play() : this.pause()" >
        <source src="videos/ParisisBurning_660x370_I_went_to_a_ball.mp4" type="video/mp4">
        Your browser does not support the video tag.
        </video>
    </div>   

There is a "channel" button that shows the user a smaller window if pressed, where the user can view other channels by clicking on a second set of buttons next and previous buttons.

<div id="bottomVid" class="videoContainerTwo hiddenElement">

    <div class="topHorizontalButtonRow">
    <div class="buttonLeftTriangleBlue"></div>
    <div class="buttonRightTriangleBlue"></div>
    </div>

    <video loop onclick="this.paused? this.play() : this.pause()" >
    <source src="videos/Politics_Refugee_Sign.mp4"  type="video/mp4">
    Your browser does not support the video tag.
    </video>

jquery show/hide smaller window:

$(".buttonTeardropChannelBlue").click( function (){
  if( $("#bottomVid").is(':visible') ) {
      $("#bottomVid").hide();

      } else {
        $("#bottomVid").show();
      }
  });

If the user wants to watch this specific channel, she can click on the smaller window, which hides the current window and advances to the other channel. The video can be clicked on, and once that happens, the user will be directed to the next channel.

Below is the code that works perfectly to advance the video of the current selection, and it contains the videos in arranged in an array.

var Vids = (function() {
    var _currentId = -1;
    var _urls =
    ["videos/ParisisBurning_370x660_Get_Into_The_Suits_Vert.mp4","videos/ParisisBurning_370x660_School_Vert.mp4","videos/ParisisBurning_660x370_I_came_I_saw_Vert.mp4", "videos/ParisisBurning_660x370_I_went_to_a_ball.mp4"]; // literal array
    return {
        next: function() {
            if (++_currentId >= _urls.length)
                _currentId = 0;
             return this.play(_currentId);
        },
        prev: function() {
            if (--_currentId < 0)
                _currentId = _urls.length - 1;
            return this.play(_currentId);
        },
        play: function(id) {
            var myVideo = document.getElementsByTagName('video')[0];
            myVideo.src = _urls[id];
            myVideo.load();
            myVideo.play();
            return false;
       }
    }
})();

What does not work

The issue: showing and hiding multiple video lists

However, the problem starts when I want to select a different class of videos, which has the exact same code except for different videos. I have changed the name of the function to say, VidsTwo but the problem remains.

var VidsTwo = (function() {
    var _currentId = -1;
    var _urls = ["videos/Politics_Atl_We_are_the_people.mp4","videos/Politics_Atlanta_Whose_Streets.mp4",  "videos/Politics_Womens_March_Washington_CBS_VERT.mp4",
    "videos/Politics_No_bans_no_walls_America_is_home_to_all_VERT.mp4",
        "videos/Politics_Let_them_in_VERT.mp4",
    "videos/Politics_Tear it Down_JFK_VERT.mp4",
    "videos/Politics_This_is_What_America_Looks_Like_embrace.mp4",
    "videos/Politics_This_land_was_made_VERT.mp4", "videos/Politics_We_need_an_independent_investigation_town_hall.mp4",
  "videos/Politics_Just say no_town_hall_VERT.mp4", ]; // literal array

    return {
        next: function() {
            if (++_currentId >= _urls.length)
                _currentId = 0;
             return this.play(_currentId);
        },
        prev: function() {
            if (--_currentId < 0)
                _currentId = _urls.length - 1;
            return this.play(_currentId);
        },
        play: function(id) {
            var myVideo = document.getElementsByTagName('video')[0];
            myVideo.src = _urls[id];
            myVideo.load();
            myVideo.play();
            return false;
       }
    }
})();

The issue remains: the buttons will continue to play the videos of the current channel in addition to the ones of the new channel, and it will not hide the current video. I understand it happens because in the javascript code, it uses the select element by tag which is "video". and all the array lists have "video" so it is playing all of them.

What is the best solution to this problem, given that I want to be able to separate the videos into categories "channels" that will have similar thematic content, and that this categories will be called by users as they look at a second smaller window of videos?

Core questions

Is there a way to have it NOT play a selection of arrays? What can I change in the Javascript code that will indicate that these separate video arrays do not belong to the same class? How can I make it clear in the code that these videos, although they are all videos, belong to different categories and therefore can only be played if their specific category is called?

Brainstorming solutions:

  • I am thinking I would probably need a second div that will have a second row of buttons that call out the second function, since the prev and next indicate a separate variable that was declared for each class of videos...but this is getting a bit complicated for my newbie skills:)
  • Or perhaps each video on a parent class should be saved on the html itself as a hidden div and should be called by using "show
    next child of parent div", as opposed to being saved as an array on
    the javascript code?
  • The next step is adding marquee text to each video so maybe having separate hidden divs on the html itself is a better solution than having the videos stored as javascript arrays?
  • This is basically a prototype/beta for something that will become an app so there is no database yet, (which will make it easier to
    store this info eventually once I begin more in-depth user tests). This complication is for testing only:)

UPDATE: I am still curious as to what the best solution would be, however I have decided, in this case, to add divs directly to the html and use jquery's next sibling selectors. Because I will have some text specific to some videos, they won't be properly connected to the javascript arrays anyway. I find the javascript array solution "cooler" but it is perhaps not the best in the end.


Solution

  • make Vids like this:

    var Vids = function(vidArray=[]) {
    var _currentId = -1;
    var _urls = vidArray;
    return {
        next: function() {
            if (++_currentId >= _urls.length)
                _currentId = 0;
             return this.play(_currentId);
        },
        prev: function() {
            if (--_currentId < 0)
                _currentId = _urls.length - 1;
            return this.play(_currentId);
        },
        play: function(id) {
            var myVideo = document.getElementsByTagName('video')[0];
            myVideo.src = _urls[id];
            myVideo.load();
            myVideo.play();
            return false;
       }
    }
    };
    

    then prepare your url array and call Vids:

    var urls =["videos/ParisisBurning_370x660_Get_Into_The_Suits_Vert.mp4","videos/ParisisBurning_370x660_School_Vert.mp4","videos/ParisisBurning_660x370_I_came_I_saw_Vert.mp4", "videos/ParisisBurning_660x370_I_went_to_a_ball.mp4"];
    Vids(urlf).play(3); //Replace 3 with any id