views:

643

answers:

5

I'm trying to load one page into another using the .load() method. This loaded page contains a script that I want to execute when it has finished loading. I've put together a barebones example to demonstrate:

Index.html:

<html>
<head>
 <title>Jquery Test</title>
 <script type="text/javascript" src="script/jquery-1.3.2.min.js"></script>
 <script type="text/javascript">
  $(document).ready(function()
  {
    $('#nav a').click(function()
    {
      $('#contentHolder').load('content.html #toLoad', '', function() {});        
      return false;
    });
  });
 </script>    
</head>
<body>
 <div id="nav">
  <a href="content.html">Click me!</a>
 </div>
 <hr />
 <div id="contentHolder">
  Content loaded will go here
 </div>
</body>
</html>

Content.html:

<div id="toLoad">
 This content is from content.html

 <div id="contentDiv">
    This should fade away.
 </div>

 <script type="text/javascript">
  $('#contentDiv').fadeOut('slow', function() {} );
 </script>
</div>

When the link is clicked, the content should load and the second paragraph should fade away. However it doesn't execute. If I stick a simple alert("") in the script of content.html it doesn't execute either.

However, if I do away with the #toLoad selector in the .load() call, it works fine. I am not sure why this is, as the block is clearly in the scope of the #toLoad div. I don't want to avoid using the selector, as in reality the content.html will be a full HTML page, and I'll only want a select part out of it.

Any ideas? If the script from content.html was in the .load() callback, it works fine, however I obviously don't want that logic contained within index.html.

I could possibly have the callback use .getScript() to load "content.html.js" afterwards and have the logic in there, that seems to work? I'd prefer to keep the script in content.html, if possible, so that it executes fine when loaded normally too. In fact, I might do this anyway, but I would like to know why the above doesn't work.

A: 

Why calling the JS is the load callback? That would be cleaner

marcgg
You mean as I've described in the last paragraph? This is possible, but I would like to know why the above approach doesn't work. Am I doing something wrong or is it a bug in jquery?
PirateKitten
A: 

Try executing that function on document ready

<script type="text/javascript">
   $(document).ready(function(){
      $('#contentDiv').fadeOut('slow', function() {} );
   })  
</script>

Could be because JS is trying to execute the function while still generating the DOM. IMO, this approach isn't very good to begin with. It's like accessing public variables in private functions.

Mike
I believe I also tried this and it didn't work. Even a simple alert("") in the script block, which won't require the DOM, doesn't execute.
PirateKitten
A: 

Why is toLoad in a separate document? I would just put toLoad and its children in index.html and set them display:none in your stylesheet, then attach the jQuery show() and hide() functions to an onclick handler to make things appear or disappear.

Will Peavy
And if you have 20 pages of 50kb content, you're then making the user load up ~1mb page every time, even if they're only interested in 1 of the pages ;)
PirateKitten
+1  A: 

There may be some restrictions on scripts executed from externally loaded content. Some of the Ajax functions will do it, some might not. For some irrational reason, I expect using .load() with a content selector to not execute scripts. This is probably some undocumented, but intentional, behavior.

Remember, you can always use a callback function with .load() that invokes .getScript().

Stuart Branham
The behaviour might be intended but it seems at odds with the default behaviour when not using a selector. And as the script is in the scope of the selector, I expected it to load. If it was outside of the toLoad div, I wouldn't question it.As for your last line, that is the method I'm actually using now (see last paragraph in the question). I'm just interested in to see if this first problem is a bug or intended behaviour.
PirateKitten
+2  A: 

If you look at the jquery source, you will see that the .load() method simply removes all scripts from the loaded content (if a selector was specified).

    jQuery.ajax({
        url: url,
        type: type,
        dataType: "html",
        data: params,
        complete: function( res, status ) {
            // If successful, inject the HTML into all the matched elements
            if ( status === "success" || status === "notmodified" ) {
                // See if a selector was specified
                self.html( selector ?
                    // Create a dummy div to hold the results
                    jQuery("<div />")
                        // inject the contents of the document in, removing the scripts
                        // to avoid any 'Permission Denied' errors in IE
                        .append(res.responseText.replace(rscript, ""))

                        // Locate the specified elements
                        .find(selector) :

                    // If not, just inject the full result
                    res.responseText );
            }

            if ( callback ) {
                self.each( callback, [res.responseText, status, res] );
            }
        }
Matt