Query about parameters and function call

Asked

Viewed 354 times

5

I created a Javascript function that when run creates a tag <script> in <head> that loads an external Javascript file.

I want to make sure that after this tag is created, a second function located inside this file that has just been loaded is called, but part of the name of this second function is the parameter of the first function. Here is an example:

I start by creating the tag <script>:

function funcao_um (parametro) {
    var script = document.createElement('script');
    script.src = 'nomeDoArquivo.js';
    document.getElementsByTagName('head')[0].appendChild(script);

Now that it is created, within that same function I want to call another function called "funcao_parametro();", that is in the . js file that has just been loaded.

I’ve tried using several codes like return "funcao_" + parametro + "();" and even the so controversial eval, Anyway, I tried anyway and I couldn’t, or Chrome says the function is not set or the entire script doesn’t work. Could you help me please? I’m new to Javascript and have no idea how to do this.

Note: I’m sure the other JS file is OK, so the problem is not in it.

4 answers

4

Let me get this straight: you want to call a function (loaded preview!) whose name you have in string form, right?

Just use the window object!

Every function we simply call global in Javascript is actually part of the window object (which is the current window, or tab if you prefer).

Let us use as an example the function foo:

function foo() {
    alert('foo!');
}

The function foo is a property of the window object. That is, there are three ways to call this function:

  • Only foo().
  • More fully: window.foo().
  • Or else: window['foo']().

Note that in the third example we use a string with the method name (foo). Remember that, roughly speaking, a Javascript object is just one "big hashmap".

The third example would suit you!


Why the eval didn’t work?

Following the example above, eval('foo()') function. I can’t tell you why in your case it didn’t work...

And of course, I won’t get into the discussion of not be used the function eval 'Cause you’ve proven to understand a little bit about it (:


p.s.: consider doing otherwise

Using the name of a reference to be called programmatically can mean a maintenance and/or confusing difficile code (especially if the code grows).

Remember that in Javascript functions are first-class citizens. That is, functions can be returned and assigned to variables:

function obterAcao() {
    return function() { alert('ação!'); }
}

var acao = obterAcao();
//...
acao();

Maybe using functions like this will make your code more readable and maintainable. Tip.

  • 1

    I think the eval did not work because it is trying to invoke the function without waiting for js loading.

2

You’re doing it the right way. This is all that’s missing:

script.setAttribute('type','text/javascript'); 

to tell the Browser what kind of content it is.

Give a look at this example and notice that the alert appears twice. One when loading, and another after 5 seconds, as the recem inserted function is now present/in the scope of the code.

function funcao_um(parametro) {
    var script = document.createElement('script');
    script.setAttribute('type','text/javascript'); 
    script.src = 'https://rawgit.com/SergioCrisostomo/version-files/master/soPT_script1.js';
    document.getElementsByTagName('head')[0].appendChild(script);
}
funcao_um();
setTimeout(function(){
  dentroDoScript();
}, 5000)

And inside the external file I have this:

function dentroDoScript(){
     alert('Estou vivo!');
}
dentroDoScript();

2

To include a script dynamically, use the following function:

function include(url, callback, conteudo) {
    var script = document.createElement('script');

    script.type = 'text/javascript';
    script.async = 'async';
    script.defer = 'defer';
    script.src = url;
    if (conteudo) script.innerText = conteudo;

    if (script.readyState) {
        script.onreadystatechange = function () {
            if (script.readyState === 'loaded' || script.readyState === 'complete') {
                script.onreadystatechange = null;
                callback && callback();
            }
        }
    }
    else {
        script.onload = callback;
    }

    document.body.appendChild(script);
}

And use it like this:

include('/meuscript.js', function() {
    // código aqui
});

One more example, dynamically loading jQuery:

include('http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.js', function() {
    alert($('body').html());
}); 

2

If the second function is in the global scope, just invoke it from the object window. Also remember to wait for the loading of the script as indicated in the other replies:

function funcao_um (parametro) {
    var script = document.createElement('script');
    script.src = 'nomeDoArquivo.js';
    document.getElementsByTagName('head')[0].appendChild(script);
    script.onload = function() {
        // invoca a função do segundo arquivo
        window["funcao_" + parametro]();
    }
}
  • I tried to do it your way but it didn’t work, gave the error "Uncaught Typeerror: Undefined is not a Function" on the line right after your comment.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.