Javascript - Uncaught Referenceerror: {funcao} is not defined

Asked

Viewed 1,928 times

1

Hello, my friends! Good evening!

I am a beginner in Javascript and I am faced with the following situation: I have a script called js widget. on my home page and this script performs a request in search of a "complementary" html, on a second page called php widget.. On this second page (widget.php) I have a Javascript function.

The problem is this... when I make the request with Xmlhttprequest, everything I need (html and js) is placed on my home page (I can see inspecting), but the function returns me the following error: Uncaught Referenceerror: test is not defined

That is, the function coming from the.php widget is written, but not executed. It follows the summary of my code:

index.html

<!DOCTYPE html>
<html>
<head>
    <title>Teste</title>
</head>
<body>
<script async="" src="https://meusite.com/widget.js"></script>
</body>
</html>

js widget.

url = 'https://meusite.com/widget.php';
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) { 
        var resp = this.response; 
        var el = document.querySelector('body');
        var html = '<div>'+resp+'</div>';
        el.insertAdjacentHTML('beforeend', html);  
    }
};
xhr.open('GET', url, true);
xhr.send();

php widget.

<h1>Título</h1>
<p>Descrição</p>
<button onclick="teste();">Ok</button>

<script type="text/javascript">
    function teste() {
        alert('Ok!');
    } 
</script> 

Follow the return images.

When loading:

inserir a descrição da imagem aqui

After calling the function manually:

inserir a descrição da imagem aqui

One important thing: I can’t use jQuery. In fact, I’ve tried it and it works very well. It needs to be with pure Javascript. I’ve also tried it with innerHTML and Eval(), and I couldn’t make it work.

So that’s it, guys. Does anyone know why this is happening and how can I fix it? Thank you all very much!

  • Tag <script type="text/javascript"> remove the attribute type="text/javascript" in HTML5 suffice <script>

  • Change the import form of these files bro.

1 answer

1


When you load a chunk of script via AJAX, it is included in the DOM but is not loaded into the JS memory, so the code is not executed and the functions do not exist. What you can do is check if the return of AJAX has tags <scripts> and insert on the page through document.createElement("script"). Through this method, the script is loaded into memory.

Only instead of using me var html = '<div>'+resp+'</div>'; to mount the new div, use var html = document.createElement("div"); to create the div and enter the AJAX response through the .innerHTML in that div and then insert everything in the page with el.appendChild(html);.

var html = document.createElement("div"); //  cria a div
html.innerHTML = resp; // insere na div a resposta do AJAX
el.appendChild(html); // insere no body

After that, you will search inside this new div inserted some tag script:

var scripts = html.querySelectorAll("script");

And check if it exists with a if:

if(scripts.length){
}

If there is the scripts.length will return a value greater than 0. Within the if you make a loop by concatenating all the contents of the tags into a variable script existing and at the same time removing them from the DOM, then inserting a new tag script in the body with the concatenated content:

if(scripts.length){
  var codigos = '';
   for(var sc = 0; sc < scripts.length; sc++){
      codigos += scripts[sc].innerHTML;
      scripts[sc].outerHTML = ''; // remove do DOM
   }
   script = document.createElement("script");
   script.innerHTML = codigos;
   el.appendChild(script);
}

This way the page will have a new tag script with all the code of (or) script returned by AJAX and will be loaded into Javascript memory to be executed. See the full code:

url = 'https://meusite.com/widget.php';
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) { 
        var resp = this.response;
        var el = document.querySelector('body');
        var html = document.createElement("div");
        html.innerHTML = resp;
        el.appendChild(html);
        var scripts = html.querySelectorAll("script");
        if(scripts.length){
           var codigos = '';
            for(var sc = 0; sc < scripts.length; sc++){
               codigos += scripts[sc].innerHTML;
               scripts[sc].outerHTML = '';
            }
            script = document.createElement("script");
            script.innerHTML = codigos;
            el.appendChild(script);
        }
    }
};
xhr.open('GET', url, true);
xhr.send();

Notice I used el.appendChild(html); to insert the div with the return of AJAX at the end of the body, but you could also use the method .insertAdjacentHTML() as follows:

el.insertAdjacentHTML('beforeend', html.outerHTML);
  • Thank you so much for the help and explanation, @sam! It worked out that it’s a beauty! Hugs!

Browser other questions tagged

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