Search code examples
javascripthtmlajaxdominnerhtml

Run A JavaScript Function Written In Called/Responce Data Of AJAX In Main Page


My problem is that I have a JavaScript function written in a PHP file and when I call it from AJAX request, I want to run that JavaScript function on the main page too after successful AJAX request. As an example, I have a main.html file where I have written an AJAXX function as below.

main.html

<script type="text/javascript">
/* AJAX Function
----------------------------------------------- */
function ajaxFunction() {
    var FD = new FormData();
    var ajx = new XMLHttpRequest();
    ajx.onreadystatechange = function () {
        if (ajx.readyState == 4 && ajx.status == 200) {
            document.getElementById("mainContent").innerHTML = ajx.responseText;
            hello();  //Uncaught ReferenceError: hello is not defined
        }
    };
    ajx.open("POST", "/example.php", true);
    ajx.send(FD);
    document.getElementById("mainContent").innerHTML = 'Loading...';
    return false;
}
</script>

And my example.php file contains a JavaScript function as

example.php

<?php
echo 'Some contents and functions';
echo '<script type="text/javascript">
   function hello() {
       alert("Hello");
    }
   </script>';
echo 'Some contents and functions';
?>

Now when I run index.html file, I get Uncaught ReferenceError: hello is not defined error in console rest I am seeing the function body is written on HTML page while inspecting elements on-page.

As I know that innerHTML does not run scripts. So what's the workaround to this problem. You can view the below-linked answer also that I think is related to my question but tried and not working with my problem.

Researched Questions/Answers:


Solution

  • As I shared and you know that innerHTML does not run scripts. so we have to look around it then I found a solution on StackOverflow and I am sharing here with this problem's answer.

    main.html

    <script type="text/javascript">
    /* AJAX Function
    ----------------------------------------------- */
    function ajaxFunction() {
        var FD = new FormData();
        var ajx = new XMLHttpRequest();
        ajx.onreadystatechange = function () {
            if (ajx.readyState == 4 && ajx.status == 200) {
                setInnerHTML(document.getElementById("mainContent"), ajx.responseText); // does run <script> tags in HTML
                hello();
            }
        };
        ajx.open("POST", "/example.php", true);
        ajx.send(FD);
        document.getElementById("mainContent").innerHTML = 'Loading...';
        return false;
    }
    
    //https://stackoverflow.com/a/47614491/3170029
    var setInnerHTML = function(elm, html) {
      elm.innerHTML = html;
      Array.from(elm.querySelectorAll("script")).forEach(oldScript => {
        const newScript = document.createElement("script");
        Array.from(oldScript.attributes)
          .forEach(attr => newScript.setAttribute(attr.name, attr.value));
        newScript.appendChild(document.createTextNode(oldScript.innerHTML));
        oldScript.parentNode.replaceChild(newScript, oldScript);
      });
    }
    </script>
    

    Its concept is clear. When you get the response data from PHP file then first extract <script ..... </script> tags from it and add them in index.html file hear by using createElement('script') and copy all the script to this then you can easily call your function after response data anywhere.

    In other words, You can create an executing script element outside of that initial parse using the DOM method of calling createElement('script'), setting its src/content, and adding it to the document. The alternative is what jQuery's getScript90 does.