Calling a JavaScript function returned from an Ajax response

Solution 1:

I think to correctly interpret your question under this form: "OK, I'm already done with all the Ajax stuff; I just wish to know if the JavaScript function my Ajax callback inserted into the DIV is callable at any time from that moment on, that is, I do not want to call it contextually to the callback return".

OK, if you mean something like this the answer is yes, you can invoke your new code by that moment at any time during the page persistence within the browser, under the following conditions:

1) Your JavaScript code returned by Ajax callback must be syntactically OK;
2) Even if your function declaration is inserted into a <script> block within an existing <div> element, the browser won't know the new function exists, as the declaration code has never been executed. So, you must eval() your declaration code returned by the Ajax callback, in order to effectively declare your new function and have it available during the whole page lifetime.

Even if quite dummy, this code explains the idea:

<html>
    <body>
        <div id="div1">
        </div>
        <div id="div2">
            <input type="button" value="Go!" onclick="go()" />
        </div>
        <script type="text/javascript">
            var newsc = '<script id="sc1" type="text/javascript">function go() { alert("GO!") }<\/script>';
            var e = document.getElementById('div1');
            e.innerHTML = newsc;
            eval(document.getElementById('sc1').innerHTML);
        </script>
    </body>
</html>

I didn't use Ajax, but the concept is the same (even if the example I chose sure isn't much smart :-)

Generally speaking, I do not question your solution design, i.e. whether it is more or less appropriate to externalize + generalize the function in a separate .js file and the like, but please take note that such a solution could raise further problems, especially if your Ajax invocations should repeat, i.e. if the context of the same function should change or in case the declared function persistence should be concerned, so maybe you should seriously consider to change your design to one of the suggested examples in this thread.

Finally, if I misunderstood your question, and you're talking about contextual invocation of the function when your Ajax callback returns, then my feeling is to suggest the Prototype approach described by krosenvold, as it is cross-browser, tested and fully functional, and this can give you a better roadmap for future implementations.

Solution 2:

Note: eval() can be easily misused, let say that the request is intercepted by a third party and sends you not trusted code. Then with eval() you would be running this not trusted code. Refer here for the dangers of eval().


Inside the returned HTML/Ajax/JavaScript file, you will have a JavaScript tag. Give it an ID, like runscript. It's uncommon to add an id to these tags, but it's needed to reference it specifically.

<script type="text/javascript" id="runscript">
    alert("running from main");
</script>

In the main window, then call the eval function by evaluating only that NEW block of JavaScript code (in this case, it's called runscript):

eval(document.getElementById("runscript").innerHTML);

And it works, at least in Internet Explorer 9 and Google Chrome.

Solution 3:

It is fully possible, and there are even some fairly legitimate use cases for this. Using the Prototype framework it's done as follows.

new Ajax.Updater('items', '/items.url', {
    parameters: { evalJS: true}
});

See documentation of the Ajax updater. The options are in the common options set. As usual, there are some caveats about where "this" points to, so read the fine print.

The JavaScript code will be evaluated upon load. If the content contains function myFunc(), you could really just say myFunc() afterwards. Maybe as follows.

if (window["myFunc"])
   myFunc()

This checks if the function exists. Maybe someone has a better cross-browser way of doing that which works in Internet Explorer 6.