0

I am creating a website with a bootstrap navigation bar in my index.html. For the content like "home", "about", "diary" etc. I've created corresponding html files like such: home.html, about.html etc. I have a div container on the index.html where then those sites get loaded into using JQuery (see navbar.js).

My problem is: Those subpages like about.html include Javascripts and even a script reference to use Google Maps API. Basically my website works just fine, but I get the following error messages, when after clicking on the same element of the navigation bar twice (even when I go to another and come back):

Uncaught SyntaxError: Identifier 'x' has already been declared You have included the Google Maps JavaScript API multiple times on this page. This may cause unexpected errors.

I'm pretty sure this is because, the whole subpages are reloaded everytime and with it the scripts that are included.

What I have tried:

  • Including all scripts in the index.html - but that doesn't work of course, because the index.html doesn't included the divs that are referenced in the javascript file
  • Checking if the scripts exist with Jquery and if not add them, like here. (First answer). Now the script works the first time I go to that subpage, but not when I click it again.

I don't want to just have a huge onepage website and then make the navigation show the div home, about etc. and hide the others. That seems like a lot of data loaded if one just wants to see a certain part of the website. Also it would be a very long index with hundreds of lines of code, that would be a mess. Also I stumbled across require.js, but I am not sure if that helps me with my problem.

So my question is: How to I stop the scripts from loading over and over again? Or should I change my approach overall?

I've tried to reduce the code as much as possible:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <title>Kriegstagebuch</title>
</head>
<body>
<!-- Navigation Bar -->
<nav class="navbar navbar-expand-lg navbar-light bg-light">
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav">
            <li class="nav-item">
                <a class="nav-link" href="#" data-page="home">Home</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#" data-page="about">About</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#" data-page="diary">Tagebuch</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#" data-page="impressum">Impressum</a>
            </li>
        </ul>
    </div>
</nav>
<!-- Div container holding the desired content -->
<div class="container"></div>
<!-- Query and Bootstrap Bundle (includes Popper) -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
<script src="assets/scripts/navbar.js"></script>
</body>
</html>

navbar.js

$(document).ready(function() {
    $(".container").load("diary.html");
});

$("ul.navbar-nav li a").each(function() {
    $(this).on("click", function(){
        $(".container").load($(this).attr("data-page")+".html");
    });
});

diary.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <style>
        #map {
            height: 50px;
        }
    </style>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <script
            src="https://maps.googleapis.com/maps/api/js?key=MYAPIKEY&callback=initMap&libraries=&v=weekly"
            defer
    ></script>
    <script src="assets/scripts/diary.js"></script>
    <!--script type="text/javascript">
      NOT WORKING !
        if (polyfillAPILoaded === undefined)
        {
            $.getScript('https://polyfill.io/v3/polyfill.min.js?features=default');
            polyfillAPILoaded = true;
        }
        if (mapsAPILoaded === undefined)
        {
            $.getScript('https://maps.googleapis.com/maps/api/js?key=MYAPIKEY&callback=initMap&libraries=&v=weekly');
            mapsAPILoaded = true;

        if (diaryLoaded === undefined)
        {
            $.getScript('assets/scripts/diary.js');
            var diaryLoaded = true;
        }
    </script-->
    <title>Tagebuch</title>
</head>
<body>
<p>Diary...</p>
<div id="map">
</div>
<button id="btn"></button>
</body>
</html>

diary.js

// I do this to test if x gets redeclared, in other words the script reloaded
let x = "Test";
console.log(x);

function initMap() {
    map = new google.maps.Map(document.getElementById("map"), {
        zoom: 8,
        center: { lat: 54, lng: 20 },
        mapTypeId: "terrain",
    });
    var flightPlanCoordinates = [
        { lat: 54.409539, lng: 20.480892 },
        { lat: 54.390511, lng: 20.640833 },
        { lat: 54.383542, lng: 19.816714 },
        { lat: 54.466667, lng: 19.933333 },
    ];
    var flightPath = new google.maps.Polyline({
        path: flightPlanCoordinates,
        geodesic: true,
        strokeColor: "#FF0000",
        strokeOpacity: 1.0,
        strokeWeight: 2,
    });
    flightPath.setMap(map);
}
document.getElementById("btn").addEventListener('click', function () {
    alert("button clicked");
});
  • Simplest is to have each page only HTML and load the script when needed using dynamic script loading – mplungjan Jan 29 '21 at 11:42
  • Thanks, I will look into that. I'm not familiar with it yet – paat1234 Jan 29 '21 at 14:27
  • Now, I figured I am already doing dynamic script loading as you can see in diary.html - the part I commented out. Also I tried [this](https://cleverbeagle.com/blog/articles/tutorial-how-to-load-third-party-scripts-dynamically-in-javascript). It's like a vicious circle, because again I must put that script (which does the dynamic script loading) somewhere. So now that keeps getting reloaded over again. Is there a way to access the DOM of the diary.html (which is displayed within the index.html using javascript? If I do a simple document.getElementById() inside the index.html, it returns null. – paat1234 Jan 30 '21 at 17:55

0 Answers0