Function not working if src is a variable?

axb*_*eit 2 html javascript

With this HTML the function myFunc() can be executed. https://myurl.de/myjs.js has the function myFunc in it.

<head>
 <script type="text/javascript" src="https://myurl.de/myjs.js"></script>
 <body>
  <script type="text/javascript">
   myFunc();
  </script>
 </body>
</head>
Run Code Online (Sandbox Code Playgroud)

But with the second HTML I get an Error: Uncaught ReferenceError: myFunc is not defined.

https://myurl.de/settingsFile.js is a file that includes this url in a var: https://myurl.de/myjs.js so basically SettingsFile.UrlToMyJS is this https://myurl.de/myjs.js

<head>
 <script src="https://myurl.de/settingsFile.js"></script>
 <script type="text/javascript" id="myid"></script>
</head>
 <body>
  <script type="text/javascript">
   document.getElementById('myid').src = SettingsFile.UrlToMyJS;
   myFunc();
  </script>
 </body>
Run Code Online (Sandbox Code Playgroud)

When I console.log(document.getElementById('myid')) this is the output:

<script type="text/javascript" id="myid" src="https://myurl.de/myjs.js></script> which is correct. It looks exactly like the script in the head of the first html (with the difference that it has the id="myid").

Yet it does not work. Why and how can I fix it?

settingsFile.js:

var defaultURL = 'https://myurl.de/';
var SettingsFile = {
UrlToMyJS : defaultURL + 'myjs.js',
}
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 5

The reason it's not working is that you can't add a src to a script element that's already in the DOM — or rather, doing so doesn't do anything. The script element has already been processed.

Instead, create it and then append it:

var script = document.createElement("script");
script.onload = function() {
    myFunc();
};
script.src = SettingsFile.UrlToMyJS;
document.head.appendChild(script);
// If you need to support IE8, use the following instead of the previous line:
//document.getElementsByTagName("head")[0].appendChild(script);
Run Code Online (Sandbox Code Playgroud)

That waits for the script to load, then calls myFunc (which should exist by then).

还要注意,正如我和杰里米在评论中指出的那样,body没有加入 head,它就会继续。通常,最好也将script标签放在的末尾body(如果您未在标签上使用asyncdefer属性,或者type="module")。总而言之,就像:

<head>
    <!-- head stuff here -->
</head>
<body>
    <!-- content here -->
    <script src="https://myurl.de/settingsFile.js"></script>
    <script type="text/javascript">
    var script = document.createElement("script");
    script.onload = function() {
        myFunc();
    };
    script.src = SettingsFile.UrlToMyJS;
    document.head.appendChild(script);
    // If you need to support IE8, use the following instead of the previous line:
    //document.getElementsByTagName("head")[0].appendChild(script);
    </script>
</body>
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用document.write。这种情况可能是document.write页面主要解析期间最后至少部分适当的使用:

<head>
    <!-- head stuff here -->
</head>
<body>
    <!-- content here -->
    <script src="https://myurl.de/settingsFile.js"></script>
    <script type="text/javascript">
    document.write('<script src="' + SettingsFile.UrlToMyJS + '"><\/script>');
    </script>
    <script>
    myFunc();
    </script>
</body>
Run Code Online (Sandbox Code Playgroud)