Miloš Đakonović
Miloš Đakonović

Reputation: 3871

Dynamically loaded javascript executed twice

OK, I've got a nasty situation where everything works fine in my custom written script loader except the fact the script being loaded is executed twice.

here is complete code:

window._appCommons=window._appCommons||{};
$.loadScr = function(path, name, exportParam){
  var df = $.Deferred();
  if (! $( ['script[data-mname="', name, '"]'].join('') ).length ) {
    window._appCommons[name] = {};
    this.get(path).done(function(data){
        for (var prop in exportParam) {
            window._appCommons[name][prop] = exportParam[prop];
        }
        var scr = ['<script data-mname="' , name , '">' , data, '<\/script>'].join('');
        $(document.getElementsByTagName('head')[0]).append( scr );
        setTimeout(function(){ df.resolve(); },16);
    });
  }
  return df;
}

$.loadScr('one.js', 'onejs', {'someKey':'someValue'}).done(function(){});

The loaded script - one.js only contain console.log('something...') statement and I get this twice.

I can confirm:

and still, the same one.js, loaded once, appended once is executed twice.

So, does anyone have an idea what's happening?

UPDATE

I can now confirm that script is executed immediately after ajax loading, no matter of being appended or not. That means pure loading of javascript file, simple like $.get('one.js') executes containing javascript code. I do not know if this should happen and is there workaround or not...

Upvotes: 6

Views: 941

Answers (3)

AamirR
AamirR

Reputation: 12198

Replacing jQuery.append to native Node.appendChild fixed the issue in my case

document.head.appendChild(scriptEl);

Upvotes: 0

Miloš Đakonović
Miloš Đakonović

Reputation: 3871

For sake of completeness I have to respond to my own question - it's jQuery.get() default settings to blame - there is dataType field, which, if not set explicitly, becomes subject to what's called Intelligent Guess - and in case of loading script jQuery actually bothers to recognize javascript code and execute it.

My problem was solved by changing this.get(path).done... to:

    this.ajax({
      url: path,
      dataType: 'text'
    })
    .done//...

which doesn't execute received code, as it should be at first place.

Upvotes: 2

Praveen Kumar Purushothaman
Praveen Kumar Purushothaman

Reputation: 167182

Can you try using this? Personally tested and used script:

function loadjscssfile (filename, filetype){
    if (filetype=="js") { //if filename is a external JavaScript file
        var fileref=document.createElement('script')
        fileref.setAttribute("type","text/javascript")
        fileref.setAttribute("src", filename)
    }
    else if (filetype=="css") { //if filename is an external CSS file
        var fileref=document.createElement("link")
        fileref.setAttribute("rel", "stylesheet")
        fileref.setAttribute("type", "text/css")
        fileref.setAttribute("href", filename)
    }
    if (typeof fileref!="undefined")
        document.getElementsByTagName("head")[0].appendChild(fileref)
}

loadjscssfile("myscript.js", "js") //dynamically load and add this .js file
loadjscssfile("javascript.php", "js") //dynamically load "javascript.php" as a JavaScript file
loadjscssfile("mystyle.css", "css") ////dynamically load and add this .css file

Upvotes: 1

Related Questions