views:

172

answers:

5

I have an HTML page like so:

<html>
<body>
<div id='something'>
    ...
    <script>
    var x = 'hello world';
    </script>
    ...
</div>
</body>
</html>

On another page, I am doing this:

$.ajax({
    url: 'example.html',
    type: 'GET',
    success: function(data) {
        $('#mydiv').html($(data).find('#something').html());
        alert(x);
    }
});

jQuery, however, is not executing the javascript in the first file, even though the documentation says it does. How can I make it do that?

EDIT: Unfortunately in the real world application I am working on I don't have control over what the "included" page has. We are on the same domain, but I can't modify the code that it outputs as it is a packaged product our IT department will not let us modify.

A: 

I expect the first page is executing the JavaScript, however this is not accessible from the second page, so alert(x) will not work

If you want x returned, you'll have to output it to the AJAX response.

James Wiseman
Ah - I was about to say why this isn't the problem, but I think I just figured out what the deal is.
Pointy
A: 

Try being more explicit with your script tag:

<script type="text/javascript">
graphicdivine
That's not going to do any good at all.
Pointy
+1  A: 

I'm not totally sure about this, but it's possible that what's happening is that when jQuery builds up the fragment from $(data), the script tags are lost at that point.

If you can arrange for the included page to really be just a fragment:

<div id='something'>
  <!-- ... -->
  <script>var x = 'hello world';</script>
</div>

without any other surrounding stuff, then your success callback can do this:

success: function(data) {
  $('#mydiv').html(data);
}

Now those script tags will be noticed by the jQuery html() function, which explicitly looks for them and strips them out. It does however hold onto those script blocks, and it executes them after it finishes updating the target contents.

Pointy
A: 

you need to add the defer attribute to your script tag

<div id='something'> 
    <script type="text/javascript" defer="defer"> 
      var x = 'hello world'; 
    </script>
</div>
Yisroel
+3  A: 

As Pointy pointed out (excuse the pun), jQuery messes with the SCRIPT tags when you pass HTML to $(). It doesn't remove them though -- it simply adds them to the DOM collection produced from your HTML. You can execute the scripts like so:

$.ajax({
    url: 'example.html',
    type: 'GET',
    success: function(data) {

        var dom = $(data);

        dom.filter('script').each(function(){
            $.globalEval(this.text || this.textContent || this.innerHTML || '');
        });

        $('#mydiv').html(dom.find('#something').html());

    }
});
J-P
Genius. Thank you.
Jose Jose
It would be nice if jQuery exposed it's `evalScript` implementation. You could have then done `dom.filter('script').each($.evalScript)`, which would handle scripts with `src` atttributes as well, same like the other dom manipulation methods do.
Crescent Fresh