Search code examples
javascriptimportinclude

Javascript file import works just one time


I've got a problem with my website, I use javascript to display a customized videoplayer. I load a couple of videos from a database and show them in a row, the problem is, that the javascript just works for the first video. I know that I would have to change for example the variable names to let the script work multiple times, but is there another way to load the same script for each videoelement?

Here is my code to get a better understanding:

        while ($row = mysqli_fetch_assoc($result))
            {
            $location = "../" . $row['pfad'] . $row['video'];
            $id = $row['id'];
            ?>
            <br>
            <p><?php echo "$row[titel]"; ?></p>

            <div class="video-container">
                <div class="c-video">
                    <video id="video" class="video" src="<?php echo "$location"; ?>"></video>
                    <div class="controls">
                        <div id="process-bar" class="process-bar">
                            <div id="currentBuffer" class="currentBuffer"></div>
                            <div id="currentProcess" class="currentProcess"></div>
                        </div>

                        <div class="buttons">
                            <button id="skip-back" class="skip-back" data-skip="-10"></button>
                            <button id="play-pause"></button>
                            <button id="skip-front" class="skip-front" data-skip="10"></button>
                            <span id="videoCurrentTime" class="videoTimer"></span> <span class="videoTimer">/</span> <span id="videoTime" class="videoTimer"></span>
                            <button id="sound" class="highSound"></button>
                            <input type="range" name="volume" class="volume-slider" id="volume-slider" min="0" max="1" value="1" step="0.05">
                            <button id="fullscreen" class="fullscreen"></button>
                        </div>
                    </div>
                </div>
                <script type="text/javascript" src="../javascript/videoplayer.js"></script>
            </div>

            <br><br>
            <a href="index.php?section=editVideo&login=success&id=<?php echo "$id"; ?>" class="btn btn-warning">Video bearbeiten</a>
            &nbsp;&nbsp;&nbsp;
            <a href="index.php?section=deleteVideo&login=success&id=<?php echo "$id"; ?>" class="btn btn-danger">Video löschen</a>
            <br><br><br>
            <?php
            }

Solution

  • I think your best option here is to change how your JavaScript addresses the video player components-- one script can't be loaded multiple times without shenanigans, and doing so can cause conflicts and errors.

    I don't know how you currently do it, but as a broad overview, what you can do in your JavaScript is initialize all the players with a single script that creates multiple instances of your video player code. Something like this:

    // assuming you have jQuery, since that makes this example more concise
    class VideoPlayer {
      constructor(container) {
         // find all the subcomponents
         this.video = $(container).find('video').first()
         this.processBar = $(container).find('div.process-bar').first()
         this.buttons = $(container).find('div.buttons').first()
    
         // ... etc, do that for all things here, bind click handlers, etc
      } 
    }
    
    // wait for the page to load so all video-container elements are on the page
    // so find them, and create a new VideoPlayer for each.
    window.addEventListener('load', () => {
      const allVideos = []
      $('div.video-container').each(function () {
        allVideos.push(new VideoPlayer(this))
      })
    })
    

    This code searches for all divs with the video-container class, then creates a new VideoPlayer with that container element. The VideoPlayer then searches within itself to find and use its child elements.

    Then you can put this script tag into your document's head instead of embedding it into the video player component:

    <head>
      <script async src="js/init.js" />
    </head>
    

    As a note, if there's multiple of these video-container elements, the id attributes won't work since you can only have one of each ID in a document. But that's okay, because you can grab the containers, then search children by class like my example code does.