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.

5
  • not showing where formelements_SELECT_add() gets called Commented Apr 14, 2017 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. Commented Apr 14, 2017 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. Commented Apr 14, 2017 at 13:59
  • agree with TJ... not conceivable that those 2 lines would be ignored and the remainder would execute Commented Apr 14, 2017 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. Commented Apr 14, 2017 at 14:06

2 Answers 2

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. :-)
Sign up to request clarification or add additional context in comments.

6 Comments

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?
@DanBray: Making sure that the addEventListener("load", ... is run before you append jsEl anywhere.
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.
@T.J.Crowder I am already doing that. I will edit my answer to show the code that calls the function.
@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. :-)
|
2

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

1 Comment

I did. I just later tried other things when it wasn't working.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.