17

I've tried using .load() and $.ajax to get some HTML that needs to be appended to a container, but the Javascript within the returned HTML is not being executed when I append it to an element.

Using .load():

$('#new_content').load(url+' #content > *',function() {
    alert('returned');
});

I've also tried switching to a $.ajax call. I then extracted the script from the returned HTML after which I appended it to the container, but same problem, the JS isn't being executed or even appended in this case, and as I understand it, trying to append a <script> to a DOM element like this is frowned upon?

Using $.ajax:

$.ajax({ url: url }).done(function(response) {
    var source  = $("<div>").html(response).find('#overview_script').html();
    var content = $("<div>").html(response).find('#content').html();

    $('#new_content').html(content);
    $('<script>').appendTo('#new_content').text(source).html();

});

Ideally I would run this javascript in a callback after I have appended the HTML, but variables are being set to values that are returned from a controller.

So in summary, I am trying to get some HTML which contains JS that needs to be run after that HTML has been appended, but I have had no luck using .load() or $.ajax() as the script in the returned HTML either disappears upon appending it, or it does not execute at all.

2

3 Answers 3

22

When load() is used with a fragment selector the script element will be stripped out before the fragment is added thus the script will not get executed.

When calling .load() using a URL without a suffixed selector expression, the content is passed to .html() prior to scripts being removed. This executes the script blocks before they are discarded. If .load() is called with a selector expression appended to the URL, however, the scripts are stripped out prior to the DOM being updated, and thus are not executed. An example of both cases can be seen below:

So Try

$.get('partial.html', function(result){
    $result = $(result);

    $result.find('#content').appendTo('#new_content');
    $result.find('script').appendTo('#new_content');
}, 'html');

Demo: Fiddle

Sign up to request clarification or add additional context in comments.

5 Comments

@RobinMaben yes it should
$(result) will strip out the script content. Have you tried it?
This will not work, as $(result) will return an array, so find() will not work. You should use filter() in order to get the required element from the array.
be careful of this solution, someone might comment a script link, so you'll require another javascript file. something like XSS
Shouldn't this work then? $('#new_content').load(url).not('#content > *').remove()
4

If you know what's the script you want to execute, you can define the script somewhere else, out of the ajax response, and then call it from the callback. So instead of:

$('#new_content').load(url+' #content > *',function() {alert('returned');});

you can use

$('#new_content').load(url+' #content > *',function() {my_function(my_param);});

1 Comment

Definitely works, and is more secure than accepted answer
2

How about this code,

$('#new_content').append($('<script>').html(source));

or you can simply move your JavaScript content to seperate file and load it using

$.getScript("url to js file");

or just use,

eval(source); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.