0

I have an issue where a function is not defined when using Chrome developer tools and I am dynamically adding some html which includes a script tag, with a function inside it.

Why is the jQuery method working, whilst the Javascript method is not and gives me refreshDescription is undefined? Looking at the jQuery append method, it calls appendChild(), but using appendChild gives me an issue, refreshFunction is not defined.

var div = document.createElement("div");
div.innerHTML = "<div class='step'>" + r + "</div>";
  
$(elem).closest(".step").append(div); //refreshFunction works

elem.closest(".step").appendChild(div); //refreshFunction is not defined
James Hatton
  • 676
  • 2
  • 9
  • 28
  • Check out https://stackoverflow.com/questions/4619668/executing-script-inside-div-retrieved-by-ajax and https://stackoverflow.com/questions/1197575/can-scripts-be-inserted-with-innerhtml – JCOC611 Jul 29 '20 at 18:20
  • Thanks @JCOC611 any idea why the jQuery one makes refreshFunction available? Does it eval it under the hood somewhere? looks like it just does an appendChild itself. – James Hatton Jul 29 '20 at 18:29

1 Answers1

1

Thanks to the pointers from @JCOC611, it looks like jQuery extracts and then inserts the scripts inside a function called evalScript called from domManip():

function (args, table, reverse, callback) {
var clone = this.length > 1,
    elems;

return this.each(function () {
    if (!elems) {
        elems = jQuery.clean(args, this.ownerDocument);

        if (reverse) elems.reverse();
    }

    var obj = this;

    if (table && jQuery.nodeName(this, "table") && jQuery.nodeName(elems[0], "tr")) obj = this.getElementsByTagName("tbody")[0] || this.appendChild(this.ownerDocument.createElement("tbody"));

    var scripts = jQuery([]);

    jQuery.each(elems, function () {
        var elem = clone ? jQuery(this).clone(true)[0] : this;

        // execute all scripts after the elements have been injected
        if (jQuery.nodeName(elem, "script")) scripts = scripts.add(elem);
        else {
            // Remove any inner scripts for later evaluation
            if (elem.nodeType == 1) scripts = scripts.add(jQuery("script", elem).remove());

            // Inject the elements into the document
            callback.call(obj, elem);
        }
    });

    scripts.each(evalScript);
});

}

evalScript()

function (data) {
data = jQuery.trim(data);

if (data) {
    // Inspired by code by Andrea Giammarchi
    // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
    var head = document.getElementsByTagName("head")[0] || document.documentElement,
        script = document.createElement("script");

    script.type = "text/javascript";
    if (jQuery.browser.msie) script.text = data;
    else script.appendChild(document.createTextNode(data));

    // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
    // This arises when a base node is used (#2709).
    head.insertBefore(script, head.firstChild);
    head.removeChild(script);
}

}

James Hatton
  • 676
  • 2
  • 9
  • 28