I've made a jsbin to show the problem: http://jsbin.com/dexeqiz/edit?html,js,output
having this html:
<div id='log'></div>
<div id='scripts'></div>
and js:
$.get('...', function(){
$('#scripts')
.append("<script>$(function(){$('#log').append('<p>3</p>');});<\/script>");
$('#log').append('<p>1</p>');
$('#log').append('<p>2</p>');
});
in jquery 1 and 2
it will render in the #log:
3
1
2
but in jquery 3 it will render
1
2
3
(so 3 is added only after the whole ajax handler was completed)
this is a problem because sometimes my code expects that the code that was appended in the line before was executed before calling the next line
right now my only workaround is to put the code after .append(newhtml) inside a setTimeout, but I would prefer not to do that because it looks slightly slower for the user. I would much rather have something like $.when(append).done(function(){code})
UPDATE:
seems that this is happening because starting with jQuery 3 scripts for document ready $(function(){}); load async (https://github.com/jquery/jquery/issues/1895) and
this is my current solution: http://jsbin.com/xayitec/edit?html,js,output
After all fiddling it stands out: there is no real solution for this issue; at least none that is not very hackish or without changing the whole setup/workflow.
For the sake of completeness I leave my "answers" as they are (see everything below "LOG") and add some background information.
https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous
https://github.com/jquery/jquery/issues/3773#issuecomment-325999054
One more idea - very hackish
You can search for all scripts in the string that will be appended. Then search for all "$( function(){...} )" occurrences with regex then insert a function like "$( function(){...;executionHandler()} )" that will count down until all these constructs are resolved and then set an outer promise as resovled. But this would be quite hackish as I said at the beginning and also might be quite error prone.
LOG
Version 1, 2, 2.1 and 3 are all tested with jQuery versions 1.12.4, 2.2.4 and 3.2.1 and should work fine with all versions from jQuery 1.8 and above.
Version 1
Version 2
was kicked
Version 3
Or alternatively
Details
jQuery.when( deferreds )jQuery.get( url [, data ] [, success ] [, dataType ] )deferred.always( alwaysCallbacks [, alwaysCallbacks ] )deferred.then( doneFilter [, failFilter ] [, progressFilter ] )References