3

I use the following function to dynamically load JavaScript:

function loadJS(file, c)
{
    var jsEl = document.createElement("script");
    jsEl.type = "application/javascript";
    jsEl.src = file;
    jsEl.async = false;
    document.body.appendChild(jsEl);
    if (c) { jsEl.addEventListener('load', function (e) { c(null, e); }, false); }
    document.getElementsByTagName("head")[0].appendChild(jsEl);
}

Below is one of the functions contained within a dynamically added file:

function formelements_SELECT_add(x)
{
    console.log("add");
    alert("add");
    var id = x[1];
    var value = x[2];
    var index = x[3];
    var select = document.getElementById(id);
    var option;
    option = document.createElement("option");
    option.text = value;
    select.add(option, index);
}

I know the JavaScript file gets added correctly and the function gets executed because an option is added to the select element. Why does the alert and console.log not execute? If I click inspect, then there are no error messages.

EDIT

This is the code I use to call the function:

var typeAndElement = x[0][0] + "_" + x[0][1];
start = i + 1;
if (!window[typeAndElement])
{
    loadJS("https://websemantica.org/scripts/" + x[0][0] + "/" + x[0][1] + ".js", continueManipulatingElements(typeAndElement, actions, x, start, total));
    return;
}
else
{
    fn = window[typeAndElement + "_" + x[0][2]];
    if (typeof fn === 'function')
        fn(x);
}

I didn't want to include it initially, because I already knew it was working and it will be unclear how it works considering it is using dynamic data.

Also, I have edited the loadJS function:

function loadJS(file, c)
{
    var jsEl = document.createElement("script");
    jsEl.type = "text/javascript";
    jsEl.src = file;
    jsEl.async = false;
    if (c) { jsEl.addEventListener('load', function (e) { c(null, e); }, false); }
    document.getElementsByTagName("head")[0].appendChild(jsEl);
}

The problem appears to be solved now.

Dan Bray
  • 7,242
  • 3
  • 52
  • 70
  • not showing where `formelements_SELECT_add()` gets called – charlietfl Apr 14 '17 at 13:56
  • The function name is dynamically generated. I've not included that code because it's not really relevant considering, I've already confirmed the function gets called. – Dan Bray Apr 14 '17 at 13:58
  • 1
    If that function were being called, you would definitely be seeing that `console.log` and `alert`. If you aren't, that function isn't being called. If you're seeing an option, it's not being added by that function. – T.J. Crowder Apr 14 '17 at 13:59
  • agree with TJ... not conceivable that those 2 lines would be ignored and the remainder would execute – charlietfl Apr 14 '17 at 14:02
  • I've commented out everything, other than the first two lines. An `option` is still added to the `select`. Therefore, it must be a caching problem. – Dan Bray Apr 14 '17 at 14:06

2 Answers2

3

Three things jump out:

  1. You're appending the script to the page twice, once to document.body, and the other to document.getElementsByTagName("head")[0]. The second one will move the script from the first place to the second. You really only need to do one of those.

  2. You're looking the load event after appending the element. If the script is in cache, you can miss the event. Hook it before appending the script to the DOM.

  3. You're not doing anything in the quoted code to call the function that's defined by the script you're adding.


Other side notes:

  • No need to set type, the default is JavaScript.
  • No need to set async, all dynamically-inserted script elements are async (now, it wasn't always true).
  • As Jarosław Wlazło points out document.alert isn't a function; just alert is all you need. :-)
Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • I've commented out `document.body.appendChild(jsEl);` and now, the `alert` and `console.log` execute as expected. What do you mean by `hook it before appending the script to the dom`? – Dan Bray Apr 14 '17 at 14:15
  • 1
    @DanBray: Making sure that the `addEventListener("load", ...` is run *before* you append `jsEl` anywhere. – T.J. Crowder Apr 14 '17 at 14:18
  • 1
    Additionally, the type property of the `src` attribute is typically voided. If it's not present it falls back to `text/javascript` and not `application/javascript`. – sshow Apr 14 '17 at 14:20
  • @T.J.Crowder I am already doing that. I will edit my answer to show the code that calls the function. – Dan Bray Apr 14 '17 at 14:22
  • 1
    @DanBray: No need. But yes, once you removed the `document.body.appendChild(jsEl)`, you didn't have that problem anymore, because you're calling `addEventListener` before appending it to `head`. :-) – T.J. Crowder Apr 14 '17 at 14:24
  • I initially, had it as just `alert`, when it didn't work, I tried other things. That was before, I realised there was a caching problem. – Dan Bray Apr 14 '17 at 14:35
2

In addition: document has no alert method. It belongs to window, so you can call it like this alert('add');

Jarosław Wlazło
  • 370
  • 1
  • 3
  • 14