views:

171

answers:

2

I have found several other questions here on S.O. (and the web in general) that ask roughly this same question, but the answers always seem to suggest other ways of structuring code that avoid the need for addressing this underlying issue.

For example, many people suggest (and a good suggestion, I agree) to put your code in the jquery load method's callback, on the calling page and not the called page. However I have unique scripts that may appear in certain resources, so I would not want to do that for every load and nor do I necessarily know what these scripts will be.

Here is a test setup to demonstrate what I'm trying to do. The short summary is that when I load partial.htm from main.htm, its script does not fire.

main.htm:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>main file</title>
</head>
<body>
<ul id="links">
    <li><a href="somepage1.php">some page1</a></li>
    <li><a href="somepage2.aspx">some page 2</a></li>
    <li><a href="partial.htm">some other partial page</a></li>
</ul>
<div id="panel" style="display:none; padding:20px; background-color:#CCC;">
LOADED CONTENT WILL GO HERE
</div>
<script type="text/javascript" src="/path/to/jquery-1.3.2.min.js"> </script>
<script type="text/javascript">
$(function(){
    $('#links a').click(function() {
     var $panel = $('#panel');
     $panel.show();
     $panel.html('Please wait...');
     var href = $(this).attr('href');
     $('#panel').load(href + ' #content');
     return false;
    });
});
</script>
</body>
</html>

OK, very simple functionality on this page. Imagine there are many more links, and some of them may require scripting while others do not.

Here is partial.htm:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>partial file</title>
</head>
<body>
<div id="content">
    <p>Hey, I am the partial file!</p>
    <script type="text/javascript">
    alert('I am some JS in the partial file! But sadly I do not execute...');
    </script>
</div>
<div>
    I am some other content on the page that won't be included by jquery.load()...
</div>
</body>
</html>

Notice that my script in partial.htm does not fire. So, my question remains: how to get this to fire, excluding any answers that tell me to put this in the .load() method's callback. (This would be because I may not have the fore-knowledge of which scripts these partial pages may contain or require!)

Thank you!


Update #1:

I suppose an acceptable answer is simply "you can't." However, I'd like to know if this is definitively the case. I haven't been able to find anything that officially states this yet.

Also, when I use firebug to inspect the panel region afterwards, there is no script element present at all. It is as if it is being parsed out by load.


Update #2:

I've narrowed this down to be a problem only when using the selector as part of the href. Loading the entire "somepage.html" will execute the script, but loading "somepage.html #someregion" does not.

$panel.load('somepage.html');              // my script fires!
$panel.load('somepage.html #someregion');  // script does not fire

I'm going to try and hunt down why this may be the case in the jquery source...

+4  A: 

Well it seems that this is by design. Apparently to make IE happy, the rest of us suffer. Here's the relevant code in the jquery source:

// 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(/<script(.|\s)*?\/script>/g, ""))

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

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

I'm wondering if, instead of just stripping out the scripts, I could modify the jquery source to include them in some other way that makes IE happy? I still have yet to find anything else on the web discussing this matter, I'm sure I'm not the only person stumped by this?

Funka
Hmm. In any case, I wonder if injecting <script> tags into the DOM with .html() would make them run - I suspect not, honestly.
ijw
it does indeed work (as i mentioned in my Update #2 of the original post). Just as long as you don't supply the selector.
Funka
I rewrote the block I pasted above to be nicer about how it handles scripts when a selector is present. I made it into a `nicerload` plugin that is working great for me now. I might see about uploading it to the jquery plugins site after I've tested it with a few other browsers...
Funka
A: 

I have run across issues before with IE not running injected <script>s that didn't contain the defer attribute. This discussion thread has some good information about the topic: innerHTML and SCRIPT tag

Kevin Hakanson