Where are the scripts loaded after ajax call?

Suppose you have a simple web page that dynamically loads content that looks like this:

- main.html -

<!DOCTYPE html> <html xmlns="https://www.w3.org/1999/xhtml"> <head> <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-1.6.2.js"> </script> <script type="text/javascript"> $(function() { $.ajax({ type: 'get', cache: false, url: '/svc.html', success: function(h) { $('#main').html(h); } }); }); </script> </head> <body> <div id='main'> loading... </div> </body> </html> 

and that the loaded page uses a little Javascript in a separate file:

- svc.html -

 <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-1.6.2.js"> </script> <script type="text/javascript" src="/plugin.js" css="/plugin.css"></script> <div id='inner'> dynamically loaded content </div> 

Pay attention to the css attribute in the script tag - it indicates the stylesheet related to the script and which the script will load for us. Here's the script:

- plugin.js -

 var css = $('<link />', { rel: "stylesheet", type: "text/css", href: $('script:last').attr('css') }); $('head').append(css); 

and finally, a stylesheet that simply colors the inner div that loads, as proof that it all works:

- plugin.css -

 #inner { border: solid 1px blue; } 

now you will notice how the stylesheet loads: we look at $('script') and select the latter, then we get the css attribute and attach the link element to the document chapter.

I can visit /svc.html , and javascript starts, loads my style, everything is cool - however, if I visit /main.html , javascript starts, but does not find the plugin.js load in the $('script') array (and, therefore, the stylesheet does not load). Please note that the script plugin starts, it just does not see itself.

This is mistake? jQuery AJAX method limitation? should $('script') display all loaded scripts?

* edit *

after a lot of crying and gnashing of teeth, I decided to go for a Kevin B solution, however I can’t get it to work, mainly because the plugin.js code plugin.js started when scriptNode , but in the plugin code the node is not yet inserted and therefore not accessible in the $('script') array, so I'm still SOL. I put all the code for the review here:

http://www.arix.com/tmp/loadWithJs/

+6
source share
5 answers

JQuery code that adds HTML to the DOM always produces <script> tags. He launches them and then drops them.

An exception to this behavior is when you use $ .load () with a hack that allows you to load a page fragment:

 $.load("http://something.com/whatever #stuff_I_want", function() { ... }); 

In this case, the scripts are separated and not evaluated / executed.

+5
source

you can use $ .ajax to get html, cut the script tags yourself, add the content, and then add the script tag to the location in dom where you want it to execute as you want.

 $.ajax({...}).done(function(html){ var htmlToAppend = html; // replace all script tags with divs htmlToAppend.replace(/<script/ig,"<div class='script'"); htmlToAppend.replace(/<\/script>/ig,"</div>"); // detach script divs from html htmlToAppend = $(htmlToAppend); var scripts = htmlToAppend.find(".script").detach(); // append html to target div htmlToAppend.appendTo("#target"); // loop through scripts and append them to the dom scripts.each(function(){ var $script = $(this), scriptText = $script.html(), scriptNode = document.createElement('script'); $(scriptNode).attr('css', $script.attr('css'); scriptNode.appendChild(document.createTextNode(scriptText)); $("#target")[0].appendChild(scriptNode); }); }); 

I have not tested this code, but it is based on the code from history.js

Edit: here is a simpler solution, more suitable for your needs:

 $("#target").load(url,function(obj){ // get css attribute from script tag using the raw returned html var cssPath = obj.responseText.match(/css="(.*)"/i)[1]; $('<link />', { rel: "stylesheet", type: "text/css", href: cssPath }).appendTo('head'); }); 

since .load () breaks the script tags and then executes them, this will read the text of the raw response and get the css path from it, and then add the link element.

I'm not quite sure why this is being handled.

Edit: see comment.

 $.ajax({...}).done(function(html){ $("#target")[0].innerHTML = html; }); 
+1
source

My solution would be pretty simple

Why not download the files you need mostly when you first boot all together? Then just get the listener event. (Check if the content is just uploaded?)

The only solution to download on demand ...

You just have to AJAX call the script file itself ...

 <script type="text/javascript"> $(function () { $.ajax({ type: 'get', cache: false, url: 'svc.html', success: function(response) { if (response) { // If any response aka, loaded the svc.html file... $('#main').html(response); $.ajax({ url: 'plugin.js', dataType: 'script', success: function(reponse) { // You can now do something with the response here even... } }); } } }); }); </script> 

My way

Make some type of loader instead of the actual page when loading before displaying anything. (Lots of jQuery tutorials around the world for this.)

+1
source

Due to problems here, you cannot reload jQuery on every page. Only the main page should have a jQuery call:

 <script type='text/javascript' src='jQuery-url'></script> 

Or only one page can call it and ONLY CHILDREN (yes, .LOADed pages from there) can use jQuery.

I came across this several times before I learned my lesson. This may not be the whole answer to your problems, but it may be the beginning of their solution.

0
source

ok, after many fights, I embedded the Kevin B solution into a plugin useful to others. Improvements are welcome! (maybe i can put it on github?)

- loadWithJs.js -

 // inspired by Kevin B suggestions // at: http://stackoverflow.com/questions/8234215/where-are-scripts-loaded-after-an-ajax-call (function ($) { $.fn.loadWithJs = function (o) { var target = this; var success = o.success; o.success = function (html) { // convert script tags html = $('<div />').append( html.replace(/<(\/)?script/ig, "<$1codex") ); // detach script divs from html var scripts = html.find("codex").detach(); // populate target target.html(html.children()); // loop through scripts and append them to the dom scripts.each(function () { var script = $(this)[0]; var scriptNode = document.createElement('script'); for (var i = 0; i < script.attributes.length; i++) { var attr = script.attributes[i]; $(scriptNode).attr(attr.name, attr.value); } scriptNode.appendChild( document.createTextNode($(script).html()) ); target[0].appendChild(scriptNode); }); if (success) success(); }; $.ajax(o); }; })(jQuery); 

then the caller can do:

 $(function() { $('#main').loadWithJs({ type: 'get', cache: false, url: '/svc.html', success: function() { console.log('loaded'); } }); }); 
0
source

Source: https://habr.com/ru/post/902157/


All Articles